通过分析覆盖率数据可以决定如何修改你的测试集:1)如果覆盖率在稳步增长,那么只需要添加新的随机种子继续运行已有的测试,或者加长测试的运行时间;2)如果覆盖率增速放缓,那你需要添加额外的约束来产生更多“有意思的”激励;3)当覆盖率稳定下来,而设计的某些部分尚未被测试过,这时就需要创建更多新的测试了。
覆盖率的类型:代码覆盖率、功能覆盖率、漏洞率、断言覆盖率
代码覆盖率:衡量验证进展的最简易的方式是使用代码覆盖率。这种方式衡量的是1)多少行代码已经被执行过了
(行覆盖率);2)在穿过代码和表达式的路径中有哪些已经被执行过
(路径覆盖率);3)哪些单比特变量的值为0或1
(翻转覆盖率);4)状态机中哪些状态和状态转换已经被访问过
(有限状态机覆盖率);【仿真和编译都要加上:-cm line+cond+tgl+fsm,不用添加任何额外的
hdl代码,工具会通过分析源代码和增加隐藏代码来自动帮你完成代码覆盖率的统计,当运行完成所有测试,代码覆盖率工具便会创建相应的数据库】
功能覆盖率:设计规范里详细说明了设备应该如何运行,而验证计划里则列出了相应的功能应该如何激励、验证和测量。当你收集测量数据希望找出哪些功能已被覆盖时,你其实就是在计算“设计”的覆盖率。功能覆盖率是和设计意图紧密相连的,有时也被称为“规范覆盖率”。而代码覆盖率则是衡量设计的实现情况,设想某个代码块在设计中被漏掉的情况,代码覆盖率不能发现这个错误,但功能覆盖率可以。
漏洞率:衡量覆盖率的一个间接的方式是查看新漏洞出现的比率。一开始,当你创建测试程序时,通过观察可能就会发现很多漏洞。一旦测试程序建立并运行后,当你校对系统中的各个模块时便会发现很多漏洞出现。在设计临近流片时,漏洞率会下降,甚至有望为零。即便如此,你的工作仍不能结束,每次比率下跌时,就应该寻找各种不同的方法去测试各种边界情况。
断言覆盖率:断言最常用于查找错误,例如两个信号是否应该互斥或者请求是否被许可等,一旦检测到问题,仿真就会立刻停止。
【测试的完备性】:在开始项目时,代码覆盖率和功能覆盖率都很低。接着你开始测试,并且使用不同的随机种子反复进行到功能覆盖率不再增加。这时,创建额外的约束和测试去开发新的区域。保存那些给出高覆盖率的测试和种子组合,以备回归测试之用。如果功能覆盖率很高但代码覆盖率很低,说明可能因为验证计划不完整,你的测试没有执行设计的所有代码,这时应该回到硬件的设计规范并且更新验证计划,然后需要增加更多针对未测试的功能覆盖点。更麻烦的情形是,代码覆盖率很高但功能覆盖率很低,即使测试平台很好的执行了设计的所有代码,你还是没有把它定位到所有感兴趣的状态上,首先,查看设计是否实现了所有指定的功能。如果功能有了,但测试不到,可能需要一个形式验证工具来提取设计状态并创建适当的激励。
【功能覆盖率的简单例子】SV绿皮书P253-P255,改进功能覆盖简易的办法是仅仅增加仿真的时间或则尝试新的随机种子。
【覆盖组】覆盖组与类相似,一次定义后便可以进行多次实例化,一个覆盖组必须被实例化后才可以用来收集数据:
covergroup CovPort; //覆盖组定义
coverpoint tr.port;
endgroup
CovPort = new(); //实例化覆盖组
CovPort.sample(); //收集覆盖率
功能覆盖率的两个主要部分是采样的数据和数据被采样的时刻。当这些新数据都准备好了以后(比如一个事务结束),测试平台便会触发覆盖组,这个过程可以通过直接使用sample函数来完成;
【覆盖组的触发】1)使用sample函数;2)使用回调函数进行采样;3)使用事件触发的覆盖组;4)使用System
verilog断言进行触发;
【数据采样】
覆盖率信息是如何收集的?当你在覆盖点上指定一个变量或表达式时,SystemVerilog便会创建很多的“仓(bin)”来记录每个数值被捕捉到的次数。这些仓是衡量功能覆盖率的基本单位。如果你采样一个单比特变量,最多会有两个仓被创建。可以想见,每次覆盖组被触发,SystemVerilog都会在一个或多个仓里留下标记。在每次仿真的末尾,所有带标记的仓会被汇聚到一个新创建的数据库中。之后使用分析工具读取这些数据库就可以生成覆盖率报告。包含设计各部分和总体的覆盖率;
1.个体仓和总体覆盖率:
为了计算出一个点上的覆盖率,首先必须确定所有可能数值的个数,这也被称为域。一个仓中可能有一个或多个值。覆盖率就是采样值的数目除以域中仓的数目。
一个3比特变量的覆盖点的域是0:7,正常情况下会除以8个仓,如果在仿真过程中有七个仓的值被采样到,那么报告会给出这个点的覆盖率是7/8或是87.5%。所有这些点组合在一起便构成了一个组的覆盖率,而所有组组合在一起就可以给出整个仿真数据库的覆盖率。这是单个仿真的情形,你需要追踪覆盖率随时间的变化情况,找出变化趋势以便弄明白,应该在什么地方进行更多的仿真或是增加新的约束或测试,这样,你就能比较好的预见验证的完成时间。
2.限制自动创建仓的数目:
覆盖组选项auto_bin_max指明了自动创建仓的最大数目,缺省值是64。如果覆盖点变量或表达式的值域超过指定的最大值,SystemVerilog会把值域范围平均分配给auto_bin_max个仓
covergroup CovPort;
coverpoint tr.port
{options.auto_bin_max=2}; //分成2个仓
endgroup