功能覆盖率
概述
功能覆盖率指你对设计所实现功能特性的收集,验证的目的就是确保设计在实际环境中的行为正确。设计规范里详细说明了设备应该如何运行,而验证计划里则列出了相应的功能应该如何激励、验证和测量。
功能覆盖率是和设计意图紧密相连的,有时也称为”规范覆盖率“,而代码覆盖率则是衡量设计的实现情况。
覆盖率完备性
如果你的功能覆盖率很高但是代码覆盖率很低,这说明你列的测试点可能不够全面,有遗漏的功能没有加入到你的测试计划中,你的测试没有很好的执行设计的所有代码,这是应该回到设计规范上,更新验证计划,然后增加更过针对未测试功能的覆盖点。
如果你的功能覆盖率很低但是代码覆盖率很高,即使设计的代码都被执行了,但是你所列的覆盖点缺没有很好的覆盖到,首先要检测下dut是否实现了所有的功能,如果功能有了,但是还是测试不到,这时就需要一个形式验证工具来提取设计状态并创建合适的激励了。
功能覆盖率详细描述
`ifndef GUARD_COVERAGE
`define GUARD_COVERAGE
class coverage extends uvm_subscriber ;
packet pkt;
covergroup switch_coverage;
length : coverpoint pkt.length; //自动对length创建仓
da : coverpoint pkt.da { //手动为da创建值为p0、p1、p2、p3的四个仓
bins p0 = { `P0 };
bins p1 = { `P1 };
bins p2 = { `P2 };
bins p3 = { `P3 }; }
length_kind : coverpoint pkt.length_kind{
option.auto_bin_max = 2; //自动创建仓,最大为两个
option.weignt = 0; //该仓覆盖率在整体中不占分量,权重为0,相当于不计算此点的覆盖率
}
fcs_kind : coverpoint pkt.fcs_kind{
bins zero = {0}; //创建一个仓代表fcs_kind == 0
bins lo = {[1:3],5}; //创建一个仓代表1:3和5
bins hi[] = {[8:$]}; //创建从8到最大值创建每个值独立的仓
bins misc = default; //创建一个仓表示剩余的所有值
ignore_bins igbin = {[6:7]}; //忽略掉6和7的两个仓
illegal_bins ill_bin = {[8:9];}//如果出现值8和9遍报错的非法仓
}
port : coverpoint pkt.port {
bins port_t1 = (0=>1),(1,2=>3,4); //创建一个仓port从0翻转到1和从1翻转到3、1翻转到4、2翻转到3、2翻转到4
}
all_cross: cross length,da,length_kind,fcs_kind;//交叉覆盖率
binsof_cross : cross length ,da{
bins length_da = binsof(length)&&binsof(da.p0); //指定binsof交叉覆盖率的状态, length的值和da为p0的交叉状态
}
endgroup
function new();
switch_coverage = new();
endfunction : new
task sample(packet pkt);
this.pkt = pkt;
switch_coverage.sample();
endtask:sample
endclass
`endif
uvm_subscriber
UVM中内建了uvm_subscriber类,可以被当作观察者或者订阅者使用。
一般用在构建功能覆盖率的收集。伪代码如下:
订阅者订阅monitor中收集到的transaction,覆盖率模块,参考模型,scoreboard都是订阅者。每当monitor收集到新的transaction,自动调用write函数,将transaction广播出去(uvm_analysis_port是一个广播的port,可以对应多个接收者)至于write函数如何实现,monitor并不关心,每个订阅者的write实现不同。在覆盖率类中write具体实现就是调用sample函数,收集覆盖率。UVM通过connect函数将TLM端口连接,在订阅者和发布者之间建立了联系。
type_option和option的区别
option用于统计覆盖率时,则只会用于个别实例instance,即当option.instance=0时,则打印单个instance的覆盖率不会再把该coverpoint的覆盖率统计在内,但是对于总的所有instance的覆盖率并没有影响,还是会计算该coverpoint的覆盖率。
type_option用于统计覆盖率时,则只会用于某个类型的coverpoint,即当type_option.instance=0时,则打印单个instance的覆盖率会把该coverpoint的覆盖率统计在内,但是对于总的所有instance的覆盖率则有影响,不计算该coverpoint的覆盖率。
我们常用$get_coverage得到所有覆盖组的总的覆盖率,使用get_coverage得到单个覆盖组所有实例的覆盖率,使用get_inst_coverage得到单个覆盖组中特定实例的覆盖率。