2.2 功能覆盖率
概述
我们无法通过代码覆盖率得知要求的功能是否被实现,需要显性地通过功能覆盖率与设计功能描述做映射,继而量化功能验证的进程。
创建功能覆盖率模型需要完成以下两个步骤:
- 从功能描述文档提取拆分需要测试的功能点
- 将功能点量化为与设计实现对应的SV功能覆盖代码
覆盖组(covergroup)
- 覆盖组与类相似,在一次定义以后便可以多次进行例化。
- 覆盖组含有覆盖点(coverpoint)、选项(option)、形式参数(argument)和可选触发(trigger event)
- 一个覆盖组包含了一个或者多个数据点,全都在同一时间采集。
- 覆盖组可以定义在类里,也可以定义在模块或者程序(program)中。
class xyz;
bit [3:0] m_;int m y;
bit m_z;
covergroup cov1 @m_z; ll embedded covergroup
coverpoint m_x;
coverpoint m_y;
endgroup
function new() ; cov1 = new ; endfunction
endclass
- 覆盖组可以采集任何可见的变量,比如程序或模块变量、接口信号或者设计中的任何信号
- 在类中的覆盖组也可以采集类的成员变量·覆盖组应该定义在适当的抽象层次上
- 对任何事务的采样都必须等到数据被待测设计接收到以后。
- 一个类也可以包含多个覆盖组,每个覆盖组可以根据需要将它们使能或者禁止
class MC;
logic [3:0] m_x;local logic m_z;bit m_e;
covergroup cv1 @(posedge clk); coverpoint m_x; endgroup
covergroup cv2 @m_e coverpoint m_z; endgroup
endclass
覆盖点(coverpoint)
仓(bin)
使用coverpoint 指定采样一个变量和表达式时,sv会创建很多的bin(仓)来记录每个数值被捕捉的次数。这些bin是衡量功能覆盖率的基本单位。
数值覆盖
Covergroup的参数也可以被传递到bin的定义中
covergroup cg (ref int ra,input int low, int high )
@ (posedge clk) ;
coverpoint r {
bins good = { [low : high] };
bins bad[] = default;
}
endgroup
...
int va, vb;
cg c1 = new ( va, 0,50 ) ;cg c2 = new( vb,120,600 ) ;
值变化覆盖
除了可以覆盖数值,还可以覆盖数值的变化
value1 =>value2
value1 =>value3 =>value4 =>value5
range_list1 =>range_list2
1,5 =>6,7
trans__item [*repeat_range]
除了使用=>来表示相邻采样点的变化,也可以使用->来表示非相邻采样点的数值变化,在=>序列后的下一个时序必须紧跟=>序列的最后一个事件
3 [->3]
表示…=>3…=>3…=>3
1=>3 [->3]=>5
表示1…=>3…=>3…=>3 =>5
与[-> repeat range]类似的有[= repeatrange]也表示非连续的循环,只是与->有区别的在于,跟随->序列的下一次值变化可以发生在->结束后的任何时刻。
3 [= 2]
表示…=>3…=>3
1=>3 [=2]=>6
表示1…=>3…=>3…=>6
自动生成
如果coverpoint没有指定任何bin,那么SV将会为其自动生成bin,遵循的原则是:
- 如果变量是枚举类型,那么bin的数量是枚举类型的基数(所有枚举数值的合)
- 如果变量是整形(M位宽),那么bin的类型将是2^M和auto_bin_max选项的较小值
通配应用
- 默认情况下,数值的变化可以针对四值类型变量进行覆盖,例如bin如果包含x或者z,则表示只有该变量对应位也为x或者z的时候,bin也才可以被采样到。
- wildcard修饰符可以使得bin中包含x,z和?的数值都将用来表示0或者1,也就是通配符的意思
wildcard bins g12_15 = { 4 'b11??} ;
g12_15可以用来表示12到15之间的值,即1100,1101,1110,1111
忽略类型和非法类型
ignore_bins用来将其排除在有效统计的bin集合之外
covergroup cg23;
coverpoint a {
ignore_bins ignore_vals = { 7,8} ;
ignore_bins ignore_trans = (1=>3=>5);
}
endgroup
illegal_bins用来指出采样到的数值为非法制,如果illegal_bins被采样到,那么仿真将报错
covergroup cg3 ;
coverpoint b {
i1legal_bins bad_vals = { 1,2,3};
illegal_bins bad_trans = (4=>5=>6);
}
endgroup
交叉覆盖率(cross)
- covergroup可以在两个或者更多的coverpoint或者变量之间定义交叉覆盖率(cross coverage)
- 在对a和b产生交叉覆盖率之前,系统会先为它们隐性产生对应的coverpoint和bin,每个coverpoint都有16个自动产生的bin
- 两个coverpoint交叉以后将生成256个交叉的bin
bit [3:0] a, b;
covergroup cov @(posedge clk) ;
axb : cross a, b;
endgroup
- 除了系统会自动为交叉覆盖率生成bin以外,用户还可以自己定义交叉覆盖率的bin
- binsof()的参数可以是coverpoint或者变量,表示对应的bin总和,可以利用binsof()对其结果做进—步的过滤
int i,j;
covergroup ct;
coverpoint i { bins i[]= { [O:1] } ; }
coverpoint j { bins j[] = { [0:1] } ; }
x1 : cross i,j;
x2 : cross i,j{
bins i_zero = binsof(i)intersect { o };
}
endgroup
3. 问答题
请考虑对于目前的DUT (router),要完成对它的功能测试,从接口时序、路由功能来看,需要考虑哪些功能和对应的测试场景?考虑路桑给出的接口插件文件(包含功能覆盖率定义和采样),是否没有全部映射你给出的待测功能点?如果需要补全,你是否可以在给出的接口插件文件中,补全这部分功能覆盖率定义代码呢?请将补全的部分代码,粘贴到这里,并且在你的实验四的代码中,试运行去收集你关心的这部分功能覆盖率,在验收实验四的时候,给予必要的说明。
答:需要考虑是否各个输入端口都能输入数据,各个输出端口是否都能接收到数据;以及不同输入端口并行发送数据、同一端口发送多个数据到不同输出端,同一输出端口接收来自不同输入端口发送的数据……