覆盖率验证——代码覆盖率+功能覆盖率

本文详细介绍了覆盖率验证,包括基于覆盖率驱动的验证技术和代码覆盖率(行覆盖率、条件覆盖率等)与功能覆盖率的概念。重点阐述了功能覆盖率建模,如covergroup、coverpoint、隐式bin与显式bins、状态跳转及交叉覆盖率,并探讨了如何通过约束、随机化次数和权重dist提高覆盖率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、基于覆盖率驱动的验证技术

   采用覆盖率驱动的验证方式可以量化验证进度,保证验证的完备性。一般在验证计划中会指定具体的覆盖率目标。通过覆盖率验证可以确定验证是否达到要求。当然,达到目标覆盖率并不意味着验证就通过了,因为功能覆盖率是由人为定义的,有时候即便达到100%,也未必将所有的功能场景全部覆盖了,因为人为主观定义的功能场景有时候可能存在遗漏,所以还需要对测试用例进行迭代。

二、代码覆盖率与功能覆盖率

  1. 代码覆盖率:工具会自动搜集已经编写好的代码,常见的代码覆盖率如下:
  • 行覆盖率(line coverage):记录程序的各行代码被执行的情况。
  • 条件覆盖率(condition coverage):记录各个条件中的逻辑操作数被覆盖的情况。
  • 跳转覆盖率(toggle coverage):记录单bit信号变量的值为0/1跳转情况,如从0到1,或者从1到0的跳转。
  • 分支覆盖率(branch coverage):又称路径覆盖率(path coverage),指在if,case,for,forever,while等语句中各个分支的执行情况。
  • 状态机覆盖率(FSM coverage):用来记录状态机的各种状态被进入的次数以及状态之间的跳转情况。
  1. 功能覆盖率:`是一种用户定义的度量,主要是衡量设计所实现的各项功能,是否按预想的行为执行,即是否符合设计说明书的功能点要求,功能覆盖率主要有两种如下所示:
  • 面向数据的覆盖率(Data-oriented Coverage)-对已进行的数据组合检查.我们可以通过编写覆盖组coverage groups)、覆盖点coverage points)和交叉覆盖cross coverage)获得面向数据的覆盖率.
  • 面向控制的覆盖率(Control-oriented Coverage)-检查行为序列sequences of behaviors)是否已经发生.通过编写SVA来获得断言覆盖率(assertion coverage).

需要指出的是: 代码覆盖率达到要求并不意味着功能覆盖率也达到要求,二者无必然的联系。而为了保证验证的完备性,在收集覆盖率时,要求代码覆盖率和功能覆盖率同时达到要求。

三、功能覆盖率建模

功能覆盖率主要关注设计的输入、输出和内部状态,通常以如下方式描述信号的采样要求;

  • 对于输入,它检测数据端的输入和命令组合类型,以及控制信号与数据传输的组合情况。
  • 对于输出,它检测是否有完整的数据传输类别,以及各种情况的反馈时序。
  • 对于内部设计,需要检查的信号与验证计划中需要覆盖的功能点相对应。通过对信号的单一覆盖、交叉覆盖或时序覆盖来检查功能是否被触发,以及执行是否正确。

3.1.覆盖组——covergroup

   使用覆盖组结构(covergroup)定义覆盖模型,覆盖组结构(covergroup construct)是一种用户自定义的结构类型,一旦被定义就可以创建多个实例就像类(class)一样,也是通过new()来创建实例的。覆盖组可以定义在module、program、interface以及class中。

每一个覆盖组(covergroup)都必须明确一下内容:

  • 一个时钟事件以用来同步对覆盖点的采样;
  • 一组覆盖点(coverage points),也就是需要测试的变量
  • 覆盖点之间的交叉覆盖;
  • 可选的形式参数;
  • 覆盖率选项;
covergroup cov_grp @(posedge clk);    //用时钟明确了覆盖点的采样时间,上升沿采样覆盖点,也可省略clk,在收集覆盖率时在根据情况注明
  cov_p1: coverpoint a;//定义覆盖点,cov_p1为覆盖点名,a为覆盖点中的变量名,也就是模块中的变量名
endgroup
 
cov_grp cov_inst = new();//实例化覆盖组

  上述例子用时钟明确了覆盖点的采样时间,上升沿采样覆盖点,也可省略clk,在收集覆盖率时在根据情况注明,如下示例:

covergroup cov_grp;
  cov_p1: coverpoint a;//cov_p1为覆盖点名,a为覆盖点中的变量名,也就是模块中的变量名
endgroup
 
cov_grp cov_inst = new();
cov_inst.sample();          //sample函数收集覆盖率

  上面的例子通过内建的sample()方法来触发覆盖点的采样.

logic [7:0] address;
covergroup address_cov (ref logic [7:0] address,        //添加形式参数
       input int low, int high) @ (posedge ce);
    ADDRESS : coverpoint address {
   
      bins low    = {
   0,low};
      bins med    = {
   low,high};
    }
  endgroup
 
address_cov acov_low  = new(addr,0,10);
address_cov acov_med  = new(addr,11,20);
address_cov acov_high = new(addr,21,30);

   覆盖组中允许带形式参数,外部在引用覆盖组时可以通过传递参数,从而对该覆盖组进行复用。

3.2.覆盖点——coverpoint

  一个覆盖组可以包含多个覆盖点,每个覆盖点有一组显式bins值,bins值可由用户自己定义,每个bins值与采样的变量或者变量的转换有关。一个覆盖点可以是一个整型变量也可以是一个整型表达式。覆盖点为整形表达式的示例如下:注意覆盖点表达式写法。

class Transaction();
   rand bit[2:0]  hdr_len;       //取值:0~7
   rand bit[3:0]  payload_len;   //取值:0~15
   ...
endclass

Transaction   tr;

covergroup Cov;
   len16: coverpoint(tr.hdr_len + tr.payload_len);    //注:取值范围为0~15
   len32:coverpoint(tr.hdr_len + tr.payload_len + 5'b0);   //注:取值范围为0~31
endgroup

  当进行仿真后,len16的覆盖点覆盖率最高可达100%,而覆盖点len32的覆盖率最高只能达到23/32=71.87%。由于总的bins数量为32个,而实际最多只能产生产生len_0,len_1,len2,…,len22共23个bins,所以覆盖率永远不可能达到100%。

  如果要使覆盖点len32达到100%的覆盖率,可以手动添加自定义bins,代码如下:

covergroup Cov;
   len32:coverpoint(tr.hdr_len + tr.payload_len + 5'b0);   //注:取值范围为0~31  
                    {
   bins  len[] = 
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

SD.ZHAI

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

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

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

打赏作者

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

抵扣说明:

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

余额充值