保姆级教程超硬核包会,SystemVerilog SV 覆盖率

前言: 介绍了代码覆盖率和功能覆盖率,对其中的关键词做了简单介绍。

覆盖率

  • 验证如果没有量化,那么就意味着没有尽头。
  • 覆盖率是用来衡量验证精度和完备性的数据指标,在仿真时设计的哪些结构被触发,哪些没有被触发。
  • 如果想要得到全面的验证精度,需要多个覆盖率种类的指标。

划分覆盖率的两种方法

  • 按照覆盖率生成的方法,即隐形生成还是显性生成。
  • 按照覆盖率溯源,是从功能描述而来还是从设计实现而来。

本文主要介绍代码覆盖率和功能覆盖率。

1.代码覆盖率

  • 代码覆盖率的优势是可以由仿真工具自动收集,可以指出测试程序中设计源代码哪些被激活,哪些是非激活。
  • 代码覆盖率的数据无法直接反映哪些设计功能被测试 。

1.1 跳转覆盖率

  • 用来衡量寄存器跳转的次数,从0到1,从1到0。
  • 跳转覆盖率经常用来测试ip模块之间的基本连接性,比如检查输入端口有没有连接。

1.2 跳转覆盖率行覆盖率

  • 哪些代码被执行过哪些没有执行,一行一行检查。

1.2 分支覆盖率

  • 分支覆盖率是用来对条件语句(if/else, case, ?😃,指出其执行的分支轨迹
  • 例如判断表达式为true或false
if (parity == odd || parity == even) begin;

1.3 条件覆盖率

  • 条件覆盖率是同来衡量布尔表达式中各个条件真伪判断的执行轨迹。
if (parity == odd || parity == even) begin;
结果为 parity == odd或 parity !== odd;
	   parity == even或parity !== even.

1.4 状态机覆盖率

  • 每个状态的进入次数,状态之间的跳转次数,多个状态的跳转顺序都可以由仿真工具记录下来。

2. 功能覆盖率

  • 面向数据的覆盖率:对已进行的数据组合检查.我们可以通过编写覆盖组(coverage groups)、覆盖点(coverage points)和交叉覆盖(cross coverage)获得面向数据的覆盖率。
  • 面向控制的覆盖率:检查行为序列(sequences of
    behaviors)是否已经发生。通过编写SVA来获得断言覆盖率(assertion coverage).

面向数据的覆盖率可以协助在回归测试时,自动检测哪些功能被激活。
主要包括两个步骤:

  • 从功能描述文档提取拆分需要测试的功能点。
  • 将功能点量化为与设计实现对应的SV功能覆盖代码。

2.1 覆盖组covergroup

  • 覆盖组包含覆盖点coverpoint,选项option,形式参数argument和可选触发trigger event。
  • 一个覆盖组包含了一个或多个数据点全部在同一时间采集。
  • 通过new()来创建实例,覆盖组可以定义在module、program、interface以及class中。
  • 覆盖组可以采集任何可见的变量,比如程序模块变量。
  • 在类中的覆盖组也可以采集类的成员变量。
  • 一个类可以包含多个覆盖组,每个覆盖组根据需要使能或禁止。
  • 覆盖组与类相似,在一次定义后可以进行多次例化。

通过下段代码来简单了解。

enum{ red, green, blue } color; 
bit[3:0] pixel_adr , pixel_offset, pixel_hue;
covergroup g2 @(posedge clk); //在上升沿对里边的变量采样
	hue: coverpoint pixel_hue; // 对pixel_hue采样,hue是这个coverpoint的名字
	offset: coverpoint pixel_offset; //对pixel_offset采样	
	axc : cross color , pixel_addr;//对两个变量可以组合的值都做考虑。color有3中可能性,pixel_addr有16钟可能性,一共是3*16
	all: cross color, hue, offset;
endgroup
g2 cg_inst = new();//实例化覆盖组

从这段代码可以看出

  • 通过covergroup …endgroup来定义覆盖组。
  • 内部可以定义多个coverpoint。
  • 通过new()来创建实例。

如果不在声明时指定采样事件,该覆盖组只能依赖sample();

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

2.1 仓bins

  • 一个coverpoint可以对应多个bin(仓)
  • coverpoint对数据的采样发生在covergroup采样的时候。
  • 关键词bins可以用来将每个感兴趣的数值均对应一个独立的bin,或者将所有值对应到一个共同的bin
  • iff语句可以用在bin的定义,它表示条件为false。那么在采集该bin的时候,该bin 的采样数目不会增长。

下段代码为bins的简单用法。

bit [9:0] v_a;
	covergroup cg @(posedfe clk); 
	coverpoint v_a{ //a是一个bins,b里有
		bins a = { [0:63] ,65 };  //
		bins b[] = { [127:150] ,[148:191] };//把68个数在b里分配,具体分成几个部分系统说了算
		bins c[] = { 200 ,201,202}; //三个bins
		bins d ={ [1000:$] };
		bins other[ ] = default; // 除了上边出现过的数,剩下的数归在了default
		}
	endgroup
  • covergroup的参数也可以被传递到bin的定义中。
  • input只是一个快照,ref是无时无刻的引用。
covergroup ch (ref int ra, input int low, int high)
	@(posedge clk);
		coverpoint r {
			bins good = { [low : high] } ;
			bins bad[] = default;
			}
endgroup	 

可以通过iff在一些情况下禁止coverpoint的采集

covergroup g4;
	coverpoint s0 iff(!reset);
endgroup
covergroup cg(ref int x , ref int y, input int c);

在定义coverpoint时可以不给名字也可以给,给了名字后方便进一步处理

coverpoint x;  //定义x
	cx: coverpoint x;//定义x并起名为cx
	b: coverpoint x;
endgroup

2.2 with

定义bin时,可以使用with来进一步限定其关心的数值,with可以用表达式或者函数衡量

	a: coverpoint x{
	bins mod3[] = { [0:255]} with (item % 3 == 0) ; //item 是一个隐形变量,不需要声明,代表的是该bins里的所有值
	}

除了可以覆盖数值,还可以覆盖数值的变化。

	1,5 => 6,7//表示从1,5变到了6,7
	3[*5] //表示3=>3=>3=>3=>3
	3[*3:5] //表示3=>3=>3或3=>3=>3=>3或3=>3=>3=>3=>3
	3[->3] 表示有三次变化,使得值为3,但这三次变化不一定相邻
	...=>3....=>3...=>3

2.3 wildcard和通配符

  • 如果bin包含x或z则表示只有该变量对应位也为x或z的时候,bin才可以被采样到。
  • wildcard修饰符可以使得bin中包含x,z和?的数值都将用来表示0或者1。
	wildcard bins g12_15 = {4'b11?? }; //表示只关心高两位是否为11,其他位与这个bins无关。

2.3 ignore_bins

  • ignore_bins用来将其排除在有效统计的bin集合之外,也就是不关心这些
	covergroup cg2;
		coverpoint a{
			ignore_bins ignore_vals = {7,8}; /
		}
	endgroup	
  • illegal_bins用来指出采样到的数值为非法制,如果被采样到会报错。
	covergroup cg2;
	coverpoint a{
		illegal_bins bad_vals = {7,8}; /
	}
	endgroup

2.4 交叉覆盖率

  • cross会考虑两个变量组合在一起的所有可能性,我们需要在这些可能性中指出哪些是我们重点关注的数据。

  • binsof()参数表示对应的bin综合,一般对结果做进一步的过滤。

	int i,j;
	covergroup ct;
	coverpoint i { bins i[] = {[0:1]};}
	coverpoint j{bins j[] = {[0:1];}
		x1: cross i,j;
		x2: cross i,j{
		bins i_zero = binsof(i) intersect{0};
		}
	endgroup

2.5 覆盖率的选项与方法

  • at_least:覆盖阈值,定义一个bin在执行代码过程中至少触发的次数,低于这个触发次数的话,这个bin不算覆盖,默认值是1。
  • auto_bin_max:当没有bin为显示创建时,定义一个覆盖点的自动bin的最大数量,默认值为64。
  • cross_auto_bin_max:定义一个交叉覆盖的交叉积(cross product)的自动bin的最大数量,没有默认值。
covergroup cg @(posedge clk);
  c1: coverpoint addr  { option.auto_bin_max = 128;}//addr自动bin的数目最大为128
  c2: coverpoint wr_rd { option.at_least = 2;}//wr_rd的每个bin至少要触发两次,否则不算覆盖
  c1Xc2: cross c1, c2  { option.cross_auto_bin_max = 128;}//交叉积的自动bin数目最大为128
endgroup : cg

//覆盖选项如果是在某个coverpoint中定义的,那么其作用范围仅限于该coverpoint;
//如果是在covergroup中定义的,那么其作用范围是整个covergroup;

参考原文链接:https://blog.csdn.net/weixin_46022434/article/details/105451642

可能对您有帮助的参考:

保姆级超硬核包会,​System Verilog SV接口(interface )
https://blog.csdn.net/jackack/article/details/127215204
保姆级超硬核包会,System Verilog SV数组
https://blog.csdn.net/jackack/article/details/127219379
保姆级教程超硬核包会,SystemVerilog SV类(class)
https://blog.csdn.net/jackack/article/details/127247350

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值