代码编织梦想


前言

2023.3.15
2023.3.20


一、覆盖率知识

1、覆盖率类型

(1)代码覆盖率

衡量RTL代码是否被充分运行的指标,100%是验证工作完备的必要性,一般设置为95%

  • 语句覆盖率(statement coverage):指的是程序的每一行代码是否被执行过。
  • 条件覆盖率(condition coverage) :指的是每个条件中的逻辑操作数被覆盖的情况。
  • 决策覆盖率(branch coverage) :指的是在if, case, _while,repeat, forever,for和loop语句中各个分支执行的情况。
  • 事件覆盖率(event coverage):该覆盖率用来记录某一个事件被触发的次数。
  • 跳转覆盖率(toggle coverage):用来记录某个设计边界信号数据位的0/1跳转情况,例如从0到1,或者从1到0的跳转。
  • 状态机覆盖率(finite stage machine coverage) :仿真器的覆盖率功能可以识别出设计中的状态机部分,记录各种状态被进X的次数,以友状态之间的跳转情况。

(2)功能覆盖率

(2-1)覆盖率分析

  • 覆盖率稳步增长:添加种子或者加长测试
  • 增速放缓:添加额外的约束
  • 增长停止:创建新的测试
  • 覆盖率达到100%还有设计漏洞:某些功能点没有进行测试

(2-2)功能覆盖率策略

  • 收集信息而非数据:数量太大的话,应当拆分成多个小范围+边界。着眼于状态而不是某个数据
  • 只测量需要的内容:收集覆盖率的时候开销是很大的
  • 验证的完备性同时驱动高的代码覆盖率和高的功能覆盖率
    代码覆盖率低功能覆盖率高:没有执行所有的代码,验证计划也不完整
    代码覆盖率高功能覆盖率低:可以执行所有代码,没有所有功能点都测试到了

(3)断言覆盖率

断言描述本身也支持覆盖率收集,一般可以通过仿真或者硬件加速的方式来收集,也可以通过形式验证的工具来收集。

定义:用于一次性地或在一段时间对一个或者多个设计信号在逻辑或者时序上的声明性代码,也可以用其他task/function来进行断言,是等价的

关心某个信号值或者状态是否改变,断言覆盖率需要自己设置,覆盖率会被收集到一个覆盖率数据库中。

  • 在常见的仿真中,仿真器会记录断言的先决条件是否被触发,以及判断语句成功或者失败。
  • 根据选择的验证方法不同,我们可以将断言覆盖率分为:
    基于动态仿真或者硬件加速的断言覆盖率
    基于形式验证的静态断言覆盖率

2、覆盖组/covergroup

  • 需要例化才能采样数据,一次定义就可以多次实例化
  • 衡量这些变量在某些特定时间采样到的值,定义采样哪些变量、数值,定义采样事件。
  • 可在classinterfacemodule里面定义
  • 一个类可以有多个covergroup,都是独立的,可以自行使能或者禁止(之前的有constraint、randomize可以使能)
  • sample():手动采样,显示采样
    wait/@:借助已有的事件阻塞触发
//采样方式一 : sample() 
covergroup Covport;
	coverpoint port;  //没有定义数值,意思就是采样所有的值
endgroup
Covport cg1 = new();   //例化  
cg1.sample();   //手动采样

//采样方式二 : 事件触发,最好不用这种方式
event trans_ready;   //定义事件
covergroup Covport@(trans_ready);   //也可以用wait
	coverpoint port;
endgroup

3、数据采样

(1)bins/仓

  • bin/仓衡量功能覆盖率的基本单位记录每个数值被捕捉到的次数
    可以手动或者SV自动定义bin
  • :可能数值的个数。
  • 每一个coverpoint组合成covergroup的覆盖率,所有的covergroup组成整体的覆盖率。
  • 覆盖率 = 采样值的数目 / bin的数目
    例如:一个3bit变量的域是7:0,正常情况下会自动分配8个bin。如果仿真过程中有7个值被采样到,那么最终的coverpoint的覆盖率就是7/8
  • 采样变量范围太大时,系统会默认分配64bin,再将数值平均分配到64个。
    auto_bin_max:指定自动创建bin的最大数目,
  • 定义在 covergroup 的option设置会影响整个covergroup ,即当前covergroup下的所有coverpoint都被设置了。coverpoint里面的设置会覆盖covergroup的设置。
covergroup Covport;
    option.auto_bin_max = 8;//covergroup中的option
    coverpoint tr.port{
        //这个option会覆盖covergroup的设置
		option.auto_bin_max = 2;//coverpoint中的option
    }
endgroup

//-----------------------------------------------
covergroup Covkind;
	coverpoint tr.kind{
		bins zero = {0};  //1个仓代表kind=0
		bins lo = {[1:3], 5};  //1个仓表示1:3和5
		bins hi[] = {[8:$]};   //8个独立的仓代表8:15
		bins misc = default;  //1个仓表示剩余的所有值
	}
endgroup

(2)条件覆盖率

关键词iff:需要满足条件才会采样,附加条件
start/stop函数:单独使能或者关闭

covergroup Covport;
    coverpoint port iff{!vif.rstn} {bins t1 = default;}  //复位期间不采样
endgroup 

Covport cb = new();
cb.stop();
if(vif.rstn = 1'b1)begin
	cb.start();
end

(3)翻转覆盖率

covergroup Covport;
    coverpoint port{
        bins t1 = (0 => 1),(0 => 2) , (0 => 3) ;//满足其中任何一个,就会记录一次
    }
endgroup 

(4)wildcard覆盖率

X/Z/:会被当成0或者1

wildcard bins even = {3'b??0};//偶数
wildcard bins odd = {3'b??1};//奇数

(5)ignore_bins

有些coverpoint可能始终无法得到全部的域值,可以用 ignore_bins来排除不计算功能的域,最终这些值不会计入coverpoint的覆盖率

bit [2:0] low_ports;
covergroup Covport;
	coverpoint low_ports{
		ignore_bins hi = {[6,7]};   //排除6和7
	}
endgroup

(6)illegal_bins

不想要某些值,出现这些数值就会报错

coverpoint port{
    illegal_bins hi = {[6,7]};//出现6~7就停止仿真,报错
}

(7)交叉覆盖率

某一时刻多个变量之间值的组合,cross出来的数据量一般比较大,可以手动忽略一些,更好的方法是自己声明感兴趣的cross bin。
binsof:指定覆盖点 coverpoint
intersect:指定数值集

//第一种:这种写法是去忽略某些值
class Transaction;
    rand bit [3:0] kind;
    rand bit [2:0] port;
endclass
transaction tr;

covergroup Covkind;
	port: coverpoint tr.port{
		bins port[] = {[0:$]};   //port是3bit,所以是8个bin
	}
	
	kind: coverpoint tr.kind{
		bins zero = {0};  //1个仓代表kind=0
		bins lo = {[1:3], 5};  //1个仓表示1:3和5
		bins hi[] = {[8:$]};   //8个独立的仓代表8:15
		bins misc = default;  //1个仓表示剩余的所有值
	}   //这里总共11个bins,看bins的数量是看前面是数组还是变量

	cross kind, port{
		ignore_bins hi = binsof(port) intersect {7};  //忽略port为7时的11个kind bin
		ignore_bins md = binsof(port) intersect {0} && binsof(kind) intersect {[9:11]};  //忽略port为0时,kind里面的hi[]
		ignore_bins lo= binsof(kind.lo);   //忽略kind.lo,也就是当kind=1,2,3,5时忽略
	}
endgroup
//第二种:首先不去收集覆盖率,设置为0;然后去采样特定的cross交叉覆盖率
//哪个写起来更方便就可以使用哪种
class Transaction;
	rand bit a, b;
endclass

Transaction tr;

covergroup CovTrans;
	a: coverpoint tr.a{
		bins a0 = {0};
		bins a1 = {1};
		option.weight = 0; //不计算覆盖率
	}
	b: coverpoint tr.b{
		bins b0 = {0};
		bins b1 = {1};
		option.weight = 0; //不计算覆盖率
	}
	ab: cross a, b{
		bins a0b0 = binsof(a.a0) && binsof(b.b0);
		bins a1b0 = binsof(a.a1) && binsof(b.b0);
		bins b1 = binsof(b.b1);
	}
endgroup

4、覆盖选项

option:covergroup和coverpoint都可以有option

  • option.per_instance = 1 :单独列出每个covergroup实例的覆盖率
  • option.goal = xxx:覆盖率目标,一般设置为100%
  • option.comment:如果有多个covergroup实例,可以通过参数来对每一个实例传入单独的注释。这些注释最终会显示在覆盖率数据的总结报告中
  • option.weight = 0:设置覆盖率权重,定义在coverpoint中,表示不关心这个coverpoint的覆盖率
  • at_least:默认情况下,数值采样次数1次就可以计入有效的bin,可以通过修改at_least来修改每个bin的数值最少采样的次数,如果低于at_least数值,则不会被计入bin
covergroup CoverLegth;
    coverpoint tr.length;
    option.per_instance = 1; //设置覆盖选项,单独列出每一个的覆盖率
endgroup

//----------------------------------
covergroup CoverLegth(int hi,lo, string comment);//传入comment
    option.comment = comment; //设置注释
    option.per_instance = 1;
    coverpoint port{
        bins range {[lo:hi]}}
endgroup
...
Coverlength cp_lo = new(0,3,"Low port numbers");
Coverlength cp_lo = new(2,3,"Hign port numbers");

5、covergroup函数

sample():采样
get_coverage():加权后的覆盖率,返回0-100的real数值
get_inst_coverage():当前实例的覆盖率,返回0-100的real数值
set_inst_name(string):设置coverpoint的名称,体现在数据报告上
start()/stop():使能或者关闭覆盖率的收集

$get_coverage():系统函数,获得总体的覆盖率

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_42135020/article/details/129676754

IC验证——SystemVerilog学习-爱代码爱编程

一般来说,在数字IC验证中,编写testbench文件会采用verilog,但随着设计越来越复杂,为了更方便例化模块,面向对象编程的SystemVerilog(以下简称SV)越来越流行。 下文部分图片和观点摘自《芯片验证漫游指南》刘斌著 1.SV基本语法 见链接:https://blog.csdn.net/qq_39815222/article/de

SystemVerilog验证 测试平台编写指南 第九章 功能覆盖率-爱代码爱编程

全面验证设计的唯一途径是采用受约束的随机测试方法(CRT),而功能覆盖率是用来衡量哪些设计特征已经被测试程序测试过的一个指标。 如何衡量验证的进展? 依靠完善的验证计划test plan和对应的功能覆盖率coverage。 用验证计划和对应功能覆盖率的结果来指导验证的进展,这样才能站在更高的抽象层次上看待验证。 根据功能覆盖率结果来思考如何提高功能覆盖率,

IC验证面试常问88道-爱代码爱编程

IC验证面试常问题88道 Q1. 定宽数组、动态数组、关联数组、队列各自特点和使用 队列:队列结合了链表和数组的优点,可以在一个队列的任何位置进行增加或者删除元素;定宽数组:属于静态数组,编译时便已经确定大小。其可以分为压缩定宽数组和非压缩定宽数组:压缩数组是定义在类型后面,名字前面;非压缩数组定义在名字后面。Bit [7:0][3:0] nam

IC验证面试常问题88道-爱代码爱编程

Q1. 定宽数组、动态数组、关联数组、队列各自特点和使用 队列:队列结合了链表和数组的优点,可以在一个队列的任何位置进行增加或者删除元素;定宽数组:属于静态数组,编译时便已经确定大小。其可以分为压缩定宽数组和非压缩定宽数组:压缩数组是定义在类型后面,名字前面;非压缩数组定义在名字后面。Bit [7:0][3:0] name; bit[7:0] name

【路科V0】systemVerilog基础20——功能覆盖率-爱代码爱编程

概述 功能验证的目标在于确定设计有关的功能描述是否被全部实现了。 这一检查中可能会存在一些不期望的情况:(要尽量发现) 一些功能没有被实现一些功能被错误地实现了一些没有被要求的功能也被实现了        我们无法通过代码覆盖率得知要求的功能是否被实现了,而需要显性地通过功能覆盖率与设计功能描述做映射,继而量化功能验证的进程。         所以

数字ic验证工程师面试题|ic验证面试常问88道_ic观察者的博客-爱代码爱编程

Q1. 定宽数组、动态数组、关联数组、队列各自特点和使用 队列:队列结合了链表和数组的优点,可以在一个队列的任何位置进行增加或者删除元素; 定宽数组:属于静态数组,编译时便已经确定大小。其可以分为压缩定宽数组和非压缩定宽数

vertx入门学习(含代码)-爱代码爱编程

Vertx入门学习 一、Vertx是什么?二、Vertx基本概念三、Vertx能干什么?四、Vertx的技术体系五、快速体验:搭建一个简单的Vertx项目并输出Hello World六、单元测试总结 一、Ver

【git】sourcetree学习笔记-图谱理解【2023.03.17】-爱代码爱编程

本系列文章前言   之前一直用的TeamFoundation,近期要代码迁移到Gitee,组内使用SourceTree进行代码管理。故将近期的学习内容做个总结。就我个人来说,不管啥技术基本上都是现学现用,网上看教程也都是看

layui框架学习(16:表单-下)-爱代码爱编程

  除了文本框,layui官网教程及示例中还介绍了下拉框、复选框、单选框等输入元素的样式及属性设置方式。   html5中采用select标签定义下拉选择框,同时内嵌option标签定义选择项,支持option标签中使用se

vue3学习笔记-爱代码爱编程

创建/运行项目 在IDEA新建一个vue项目 nodejs(运行环境) vue的开发/编译工具(vite)是基于nodejs平台的, 所以第一步先安装nodejs,下载地址: Node.js, 安装LST(长期维护)版本即可.  npm 安装完毕后命令行会增加一个包管理工具: npm, 包管理可以理解为通过他可以下载js插件, 后续我们开发用

2023年华为认证h12-821、h12-831考试指南(包括学习视频和题库)-爱代码爱编程

一、什么是HCIP-Datacom 英文名:HCIP-Datacom-Advanced Routing & Switching Technology 中文名:培训与认证具备数通领域路由交换高阶知识和技能水平的高级工程师 二、通过认证后可以做什么?      可以胜任中到大型企业网络工程师岗位,掌握中到大型网络的特点和通用技术,具备使用华为数

2023年3月20日学习总结-爱代码爱编程

主要学习内容是: 一、安装基于 VSCode 的 esp32-idf 开发环境。 二、打开范例工程来测试开发环境和ESP32的开发板。 遇到的难点问题有: 1、遇到 命令"ESP-IDF": 配置 ESP-IDF 插件

人工智能学习07-爱代码爱编程

师兄说学目标检测之前先学分类 坏了,内容好多!学学学 感谢up主,好人一生平安 混淆矩阵 什么是混淆矩阵: 横坐标:每一列属于该类的所有验证样本。每一列所有元素对应真实类别。 纵坐标:网络的预测类别。每一行对应预

lin.security靶机学习_lin 靶机-爱代码爱编程

靶机地址:https://www.vulnhub.com/entry/linsecurity-1,244/ 靶机网络配置 先用用户名bob 密码secret登录 然后提权到root sudo awk 'BEGIN {s