前言: 介绍了代码覆盖率和功能覆盖率,对其中的关键词做了简单介绍。
覆盖率
- 验证如果没有量化,那么就意味着没有尽头。
- 覆盖率是用来衡量验证精度和完备性的数据指标,在仿真时设计的哪些结构被触发,哪些没有被触发。
- 如果想要得到全面的验证精度,需要多个覆盖率种类的指标。
划分覆盖率的两种方法
- 按照覆盖率生成的方法,即隐形生成还是显性生成。
- 按照覆盖率溯源,是从功能描述而来还是从设计实现而来。
本文主要介绍代码覆盖率和功能覆盖率。
1.代码覆盖率
- 代码覆盖率的优势是可以由仿真工具自动收集,可以指出测试程序中设计源代码哪些被激活,哪些是非激活。
- 代码覆盖率的数据无法直接反映哪些设计功能被测试 。
1.1 跳转覆盖率
- 用来衡量寄存器跳转的次数,从0到1,从1到0。
- 跳转覆盖率经常用来测试ip模块之间的基本连接性,比如检查输入端口有没有连接。
1.2 跳转覆盖率行覆盖率
- 哪些代码被执行过哪些没有执行,一行一行检查。
1.2 分支覆盖率
- 分支覆盖率是用来对条件语句(if/else, case, ?😃,指出其执行的分支轨迹
- 例如判断表达式为true或false
if (parity == odd || parity == even) begin;
1.3 条件覆盖率
- 条件覆盖率是同来衡量布尔表达式中各个条件真伪判断的执行轨迹。
if (parity == odd || parity == even) begin;
结果为 parity == odd或 parity !== odd;
parity == even或parity !== even.
1.4 状态机覆盖率
- 每个状态的进入次数,状态之间的跳转次数,多个状态的跳转顺序都可以由仿真工具记录下来。
2. 功能覆盖率
- 面向数据的覆盖率:对已进行的数据组合检查.我们可以通过编写覆盖组(coverage groups)、覆盖点(coverage points)和交叉覆盖(cross coverage)获得面向数据的覆盖率。
- 面向控制的覆盖率:检查行为序列(sequences of
behaviors)是否已经发生。通过编写SVA来获得断言覆盖率(assertion coverage).
面向数据的覆盖率可以协助在回归测试时,自动检测哪些功能被激活。
主要包括两个步骤:
- 从功能描述文档提取拆分需要测试的功能点。
- 将功能点量化为与设计实现对应的SV功能覆盖代码。
2.1 覆盖组covergroup
- 覆盖组包含覆盖点coverpoint,选项option,形式参数argument和可选触发trigger event。
- 一个覆盖组包含了一个或多个数据点全部在同一时间采集。
- 通过new()来创建实例,覆盖组可以定义在module、program、interface以及class中。
- 覆盖组可以采集任何可见的变量,比如程序模块变量。
- 在类中的覆盖组也可以采集类的成员变量。
- 一个类可以包含多个覆盖组,每个覆盖组根据需要使能或禁止。
- 覆盖组与类相似,在一次定义后可以进行多次例化。
通过下段代码来简单了解。
enum{ red, green, blue } color;
bit[3:0] pixel_adr , pixel_offset, pixel_hue;
covergroup g2 @(posedge clk); //在上升沿对里边的变量采样
hue: coverpoint pixel_hue; // 对pixel_hue采样,hue是这个coverpoint的名字
offset: coverpoint pixel_offset; //对pixel_offset采样
axc : cross color , pixel_addr;//对两个变量可以组合的值都做考虑。color有3中可能性,pixel_addr有16钟可能性,一共是3*16
all: cross color, hue, offset;
endgroup
g2 cg_inst = new();//实例化覆盖组
从这段代码可以看出
- 通过covergroup …endgroup来定义覆盖组。
- 内部可以定义多个coverpoint。
- 通过new()来创建实例。
如果不在声明时指定采样事件,该覆盖组只能依赖sample();
covergroup cov_grp;
cov_p1: coverpoint a;//cov_p1为覆盖点名,a为覆盖点中的变量名,也就是模块中的变量名
endgroup
cov_grp cov_inst = new();
cov_inst.sample(); //sample函数收集覆盖率
2.1 仓bins
- 一个coverpoint可以对应多个bin(仓)
- coverpoint对数据的采样发生在covergroup采样的时候。
- 关键词bins可以用来将每个感兴趣的数值均对应一个独立的bin,或者将所有值对应到一个共同的bin
- iff语句可以用在bin的定义,它表示条件为false。那么在采集该bin的时候,该bin 的采样数目不会增长。
下段代码为bins的简单用法。
bit [9:0] v_a;
covergroup cg @(posedfe clk);
coverpoint v_a{ //a是一个bins,b里有
bins a = { [0:63] ,65 }; //
bins b[] = { [127:150] ,[148:191] };//把68个数在b里分配,具体分成几个部分系统说了算
bins c[] = { 200 ,201,202}; //三个bins
bins d ={ [1000:$] };
bins other[ ] = default; // 除了上边出现过的数,剩下的数归在了default
}
endgroup
- covergroup的参数也可以被传递到bin的定义中。
- input只是一个快照,ref是无时无刻的引用。
covergroup ch (ref int ra, input int low, int high)
@(posedge clk);
coverpoint r {
bins good = { [low : high] } ;
bins bad[] = default;
}
endgroup
可以通过iff在一些情况下禁止coverpoint的采集。
covergroup g4;
coverpoint s0 iff(!reset);
endgroup
covergroup cg(ref int x , ref int y, input int c);
在定义coverpoint时可以不给名字也可以给,给了名字后方便进一步处理。
coverpoint x; //定义x
cx: coverpoint x;//定义x并起名为cx
b: coverpoint x;
endgroup
2.2 with
定义bin时,可以使用with来进一步限定其关心的数值,with可以用表达式或者函数衡量。
a: coverpoint x{
bins mod3[] = { [0:255]} with (item % 3 == 0) ; //item 是一个隐形变量,不需要声明,代表的是该bins里的所有值
}
除了可以覆盖数值,还可以覆盖数值的变化。。
1,5 => 6,7//表示从1,5变到了6,7
3[*5] //表示3=>3=>3=>3=>3
3[*3:5] //表示3=>3=>3或3=>3=>3=>3或3=>3=>3=>3=>3
3[->3] 表示有三次变化,使得值为3,但这三次变化不一定相邻
...=>3....=>3...=>3
2.3 wildcard和通配符
- 如果bin包含x或z则表示只有该变量对应位也为x或z的时候,bin才可以被采样到。
- wildcard修饰符可以使得bin中包含x,z和?的数值都将用来表示0或者1。
wildcard bins g12_15 = {4'b11?? }; //表示只关心高两位是否为11,其他位与这个bins无关。
2.3 ignore_bins
- ignore_bins用来将其排除在有效统计的bin集合之外,也就是不关心这些
covergroup cg2;
coverpoint a{
ignore_bins ignore_vals = {7,8}; /
}
endgroup
- illegal_bins用来指出采样到的数值为非法制,如果被采样到会报错。
covergroup cg2;
coverpoint a{
illegal_bins bad_vals = {7,8}; /
}
endgroup
2.4 交叉覆盖率
-
cross会考虑两个变量组合在一起的所有可能性,我们需要在这些可能性中指出哪些是我们重点关注的数据。
-
binsof()参数表示对应的bin综合,一般对结果做进一步的过滤。
int i,j;
covergroup ct;
coverpoint i { bins i[] = {[0:1]};}
coverpoint j{bins j[] = {[0:1];}
x1: cross i,j;
x2: cross i,j{
bins i_zero = binsof(i) intersect{0};
}
endgroup
2.5 覆盖率的选项与方法
- at_least:覆盖阈值,定义一个bin在执行代码过程中至少触发的次数,低于这个触发次数的话,这个bin不算覆盖,默认值是1。
- auto_bin_max:当没有bin为显示创建时,定义一个覆盖点的自动bin的最大数量,默认值为64。
- cross_auto_bin_max:定义一个交叉覆盖的交叉积(cross product)的自动bin的最大数量,没有默认值。
covergroup cg @(posedge clk);
c1: coverpoint addr { option.auto_bin_max = 128;}//addr自动bin的数目最大为128
c2: coverpoint wr_rd { option.at_least = 2;}//wr_rd的每个bin至少要触发两次,否则不算覆盖
c1Xc2: cross c1, c2 { option.cross_auto_bin_max = 128;}//交叉积的自动bin数目最大为128
endgroup : cg
//覆盖选项如果是在某个coverpoint中定义的,那么其作用范围仅限于该coverpoint;
//如果是在covergroup中定义的,那么其作用范围是整个covergroup;
参考原文链接:https://blog.csdn.net/weixin_46022434/article/details/105451642
可能对您有帮助的参考:
保姆级超硬核包会,System Verilog SV接口(interface )
https://blog.csdn.net/jackack/article/details/127215204
保姆级超硬核包会,System Verilog SV数组
https://blog.csdn.net/jackack/article/details/127219379
保姆级教程超硬核包会,SystemVerilog SV类(class)
https://blog.csdn.net/jackack/article/details/127247350