验证基础-验证量化及覆盖率

目录

覆盖率类型

代码覆盖率

断言覆盖率

功能覆盖率

覆盖组

数据采样

条件覆盖率

翻转覆盖率

交叉覆盖率

覆盖选项

覆盖率分析


        覆盖率是衡量设计完备性的一个指标。

        覆盖率工具会在仿真过程中收集信息,然后进行后续处理并且得到覆盖率报告,然后通过报告找出覆盖之外的区域,接着修改现有测试或者创建新的测试来填补这些盲区。每一次的随机测试我们都会得到对应的测试结果,最后我们再把这些测试结果合并,就能得到最终的覆盖率报告了。

覆盖率类型

代码覆盖率

        1.行覆盖率:多少行代码已经被执行过。

        2.路径覆盖率:在穿过代码和表达式的路径中哪些已经被执行过。

        3.翻转覆盖率:哪些单位比特变量的值为0或1.

        4.状态机覆盖率:状态机哪些状态和状态转换已经被访问过。

        代码覆盖率最终的结果用于衡量你执行了设计中的多少代码。未经测试的设计代码里可能隐藏硬件漏洞,也可能仅仅就是冗余的代码

        代码覆盖率到达100%,并不意味着验证的工作已经完成,但是代码覆盖率100%是验证工作完备性的必要条件。

断言覆盖率

        断言是用于一次性地或在一段时间对一个或者多个设计信号在逻辑或者时序上的声明性代码。断言最常用于查找错误,例如两个信号是否应该互斥,或者请求与许可信号之间的时序等,一旦检查到问题,仿真就可以立即停止。

功能覆盖率

        验证的目的就是确保设计在实际环境中的行为正确功能描述文档详细说明了设计应该如何运行,而验证计划则列出了相应的功能应该如何激励、验证和测量某个功能在设计时可能被遗漏,代码覆盖率不能发现这个错误,但是功能覆盖率可以。 

        每一次仿真都会产生一个带有覆盖率信息的数据库,记录随机游走的轨迹,把这些信息全部合并在一起就可以得到功能覆盖率,从而衡量整体的进展程度。

        如果覆盖率在稳步增长,那么添加新的种子或者加长测试时间即可;如果覆盖率增速缓慢,那么需要添加额外的约束来产生更多“有意思”的激励;如果覆盖率停止增长,然而设计某些测试点没有被覆盖到,那么需要创建新的测试;如果覆盖率为100%但依然有新的设计漏洞,那么覆盖率可能没有覆盖到设计中的某些设计功能区域。 

        完备的覆盖率测量结果和漏洞增长曲线,可以帮助确认设计是否被完整地验证过。A.如果代码覆盖率低,但功能覆盖率高,这说明验证计划不完整可能有部分功能点没被列入验证计划。B.如果代码覆盖率高,但功能覆盖率低,这说明即使测试平台很好地执行了设计的所有代码,但测试没有把设计定位到所有感兴趣的状态上。

        一般在公司里都会要求代码覆盖率和功能覆盖率都要达到95%以上。

覆盖组

        覆盖组(covergroup)与类(class)相似,一次定义后便可以多次实例化。它含有覆盖点、选项、形式参数和可选触发(trigger)。一个覆盖组包含了一个或多个数据点,全都在同一时间采集。covergroup可以定义在类中,也可以定义在 interface 或者 module 中,它可以采样任何可见的变量,例如程序变量、接口信号或者设计端口。

        一个类里可以包含多个covergroup,当你拥有多个独立的 covergroup 时,每个covergroup 可以根据需要自行使能或者禁止。covergroup 必须要被例化才可以用来收集数据。

        如果覆盖组定义在类里,实例化时可以使用最初的名字,例如上面这个例子中展现的,申明了CovPort为covergroup后,就直接对它进行了new(),实际上我们知道这只是声明该变量为covergroup类型并不是声明对象。除此种特殊的例化方式,通常使用的是下面这种:

        因为covergroup是可以例化多次的,如果采用直接把CovPort作为实例名例化,那就不能例化第二次了,而采用下面这种声明一个别的对象为CovPort类型(也即covergroup类型)显然可以例化多次,改个声明对象名字即可。

        上面的代码,在采样的时候,采用的是CovPort.sample()(调用sample()函数)的方式进行采样,这是第一种采样方式,还有第二种就是采取阻塞的方式wait或者@实现事件上的阻塞,当遇到什么事件的时候再进行采样。

数据采样

        当你在 coverpoint 指定采样一个变量或表达式时,SV会创建很多的仓(bin)来记录每个数值被捕捉到的次数。这些bin是衡量功能覆盖率的基本单位。

        covergroup 中可以定义多个coverpoint,coverpoint中可以自定义多个cover bin或者SV帮助自动定义多个cover bin。

        为了计算一个coverpoint上的覆盖率,首先需要确定可能数值的个数,这也被称为

        ※ 覆盖率就是采样值的数目除以bin的数目。例如一个3bit变量的域是0:7,正常情况下会自动分配8个bin。如果仿真过程中有7个值被采样到,那么最终该coverpoint的覆盖率为7/8。

        ※ 所有的coverpoint的覆盖率最终构成一个covergroup的覆盖率。所有的covergroup的覆盖率构成了整体的覆盖率。

        如果采样变量的域范围过大而又没有指定bin,那么系统会默认分配64个bin,将值域范围平均分配个这64个bin,例如一个16bit变量有65536个可能值,所以64个bin中的每一个都覆盖了1024个值。用户可以通过covergroup的选项auto_bin_max来指定自动创建bin的最大数目。实际操作中自动创建bin的方法并不实用,建议用户自行定义bin: 

        注意coverpoint定义使用{}而不是begin-end。大括号的结尾没有分号,和end一样。

对于hi,会分配8个bin。lo是一个bin,misc也是一个bin。左边是bin的名称,中间是bin里的数据被采样了多少次,右边意思是这个至少要收集多少次。上面这个结果来看,总共有11个bin,只有一个bin没有被收集到,那么它最终的覆盖率就是10/11。

条件覆盖率

        可以使用关键词 iff 给 coverpoint 添加条件。

        如果在采样(sample函数)的时候,使用了iff,那么收集覆盖率的时候,既要满足sample()进行采样,也要满足iff后面的条件,才会对其进行采样。还可以使用start和stop函数来控制covergroup各个独立实例的开启和关闭,如果关闭了,哪怕设了采样sample函数,也不会真的采样。

翻转覆盖率

        coverpoint 也可以用来记录变量从A值到B值的跳转情况。还可以确定任何长度的翻转次数。

    记录t1值从0翻转到1或者2或者3的次数,但凡这三个事件有一个发生,bin里面记录的次数就会加1。

忽略的bin

        三比特变量low_ports_0_5最初的范围是0:7。ignore_bins 排除掉最后两个仓,即不考虑6和7的采样值,从而把采样范围缩小到0:5.所以这个组的总体覆盖率是采样到的仓数除以总仓数,这里总仓数时是6。

非法的bin

        有些采样值不仅应该被忽略而且如果出现还应该报错。

        这种情况可以在测试平台中监测,也可以使用illegal_bins对特定的bin进行标示。 

如果出现6,7不单不能出现,而且如果出现了就会报错。

交叉覆盖率

        coverpoint 是记录单个变量或者表达式的观测值。如果想记录某一时刻,多个变量之间值的组合情况,需要使用交叉(cross) 覆盖率。 

排除部分cross bin

        比如上面的例子,假设kind有16个bin,port有8个bin,那么cross之后,它们之间就会产生8*16=128个bin,数量很多,为了减少bin的数量,我们可以采用ignore的方式来清除那些我们不关心的cross bin。 

 

        如上面的例子,port共有8个bin,kind共有11个bin。在声明两个变量的交叉覆盖率的时候,忽略了很多的交叉情况,比如当port 里值为7时,不考虑和 kind 的 bin 交叉的情况,以及 port 里值为0且 kind 里值为9-11的时候,也不考虑这种情况的交叉 bin 等。

        但是随着cross覆盖率越来越精细,更合适的方式是不使用自动分配的cross bin,而是自己声明自己感兴趣的cross bin。

        假如有两个随机变量a,b。它们带着三种感兴趣的状态{a==0,b==0}\{a==1,b==0}和{b==1}。

选择自己感兴趣的点做交叉覆盖。

覆盖选项

        如果对一个covergroup 例化多次,那么默认情况下SV会将所有实例的覆盖率加权合并到一起,如果需要单独列出每个covergroup实例的覆盖率,需要设置覆盖选项。

这样设置option后,每个实例的覆盖率都会单独计算。

        如果有多个covergroup实例,可以通过参数来对每一个实例传入单独的注释。这些注释最终会显示在覆盖率数据的总结报告中。

 

        covergroup 方法:sample()采样、get_coverage()/get_inst_coverage():获取覆盖率,返回0-100的real数值。set_inst_name(string):设置coverage的名称、start()/stop():使能或者关闭覆盖率的收集。

覆盖率分析

        使用 $get_coverage() 可以得到总体的覆盖率。

        也可以使用 covergroup_inst.get_inst_coverage( ) 获取单个 covergroup 实例的覆盖率

        如果覆盖率水平在一段时间之后没有提高,那么这个测试就应该停止。重启新的随机种子或者测试可能有望提高覆盖率,重新限定随机的约束也能对提高覆盖率有所帮助。

 

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
在UVM验证中,测试用例和覆盖率是被广泛关注的两个重要方面。 测试用例是验证工程师编写的针对设备或系统的特定功能或场景的输入。它们是一系列的测试向量,用于模拟各种可能的工作条件和输入情况,以确保设计在各种情况下都能正常工作。测试用例是验证过程中的核心,通过执行它们,我们可以发现设计中的错误、漏洞或不足之处。 覆盖率是用来衡量测试用例的有效性以及对设计进行全面覆盖的度量标准。它能够量化验证环境对设计的测试覆盖程度,从而帮助验证工程师评估验证品质。通常有三种常见的覆盖类型:语句覆盖、分支覆盖和条件覆盖。测试用例的执行结果与设计中的各种语句、分支和条件的覆盖情况相比较,从而确定验证工作的完整性。 测试用例和覆盖率之间存在着密切的关系。通过对测试用例进行分析,可以确定哪些部分没有得到充分的测试,进而有针对性地编写新的测试用例。同时,覆盖率分析也可以评估现有测试用例的覆盖范围和覆盖质量。通过监控覆盖率的变化,可以有效地跟踪验证的进展,并及时进行调整和改进。 总结而言,测试用例和覆盖率在UVM验证中都是非常重要且不可或缺的。它们共同构成了验证活动的核心,并通过不断迭代与完善,使验证工程师能够发现设计中的问题,并为设计团队提供优质的验证结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不吃葱的酸菜鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值