• 正文
  • 相关推荐
申请入驻 产业图谱

记录几个SystemVerilog的语法——覆盖率

08/04 09:01
2605
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

1、前言

通常说的覆盖率有两种类型:code coverage(代码覆盖率)functional coverage(功能覆盖率)。代码覆盖率是使用EDA工具自动从设计代码里提取出来的,功能覆盖率是用户指定的,用于衡量测试设计意图和功能进展。因此,功能覆盖率有两个关键点:

它是用于指定的,而不是根据设计代码自动推测生成的;

它是基于设计需求,独立于实际设计代码和结构;

覆盖率主要由覆盖率组(covergroup)、覆盖率点(coverage point)、交叉覆盖率(cross coverage)、覆盖率选项(coverage option)覆盖率方法(coverage method)组成的。

2、covergroup

Covergroup用于构建覆盖率模型,它将覆盖率模型和规范封装起来,内部可以包含以下组件:

用于coverage point同步和采样的时钟事件;

Coverage points;

Cross coverage;

可选的参数;

Coverage options

Covergroup是用户定义的类型,可以定义在package、module、program、interface、checker或class里面。类似于class,covergroup可以在多处地方调用new()构造函数例化。如下所示,covegroup name是cg,通过new()构造函数,创建了cg的例化cg_inst。

covergroup cg; ... endgroupcg?cg_inst?=?new;

covergroup可以通过new(xx)构造函数传递参数进去,参数的类型只能是ref(会被处理成const ref)或input,而不能时output或inout。

可以通过@event或sample()方法来指定coverage何时采样。Covergroup可以包含一个或多个coverage points。Coverage point可以覆盖一个变量或一个表达式。Coverage point内部可以包含一组bins(仓),用于采集values或value transitions。用于采集value 集合的bin称为state bins,用于采集value transitions的bin称为transition bins。

也可以将coverage group嵌入到class定义中,这是一种常见的做法,它提供了一种简单的方式去覆盖类中的属性,可以保护类的封装性,这种方式称作embedded covergroup declaration。

3、coverage point

Coverpoint表达式(包括iff condition)的采样是发生在covergroup被采样的时候。Coverpoint会创建一个层次化范围且可选的labeled。如果有使用label,那么该label就是coverage point的名字。该名字也可以用于cross coverage 和访问coverpoint中的方法。如果没有指定label且coverpoint只和一个单一变量关联,那么该变量名可以是coverpoint的名字,其它情况,由工具实现定义,但该自动生成的名字只是用于coverpoint报告,不能被其它地方语言引用。

Coverpoint bin将一个name和count与一组value或value transition 序列联系起来,当一个bin指定的value或value transition 序列每一次满足时,相应的count加1。每一个bins的后面都可以跟着iff construct来指定该bins是否满足采样条件,如果是false,那么count肯定不会增加的。Transition bin在每一个sample中,最多只能增加1,不管同时有几个hit同一个bins。

bins允许对于给定范围列表的每一个value创建一个独立的bin,可以在bin name后面加上[]就可以了,或者如果要把给定范围列表分配到几个bin内,可以在[]里加上正整数expression。如果bins的固定个数小于values的指定个数,那么尽力采用均分,无法均分,最后一个全部兜着。如果bins的个数大于values的指定个数,那么有一些bins将会是空的。

bins允许对于范围列表创建一个单一的bin,也就是bin name的等号后面使用{}指定一组values。

对于范围列表,允许使用[ expression : $ ] or [ $ : expression ]。

如果没有指定bins的话,coverpoint bin会自动创建,创建的最大个数为auto_bin_max(coverage option)指定的。

default可以用于替代没有被显式定义的bins中指定的其它值,对于coverpoint覆盖率的计算不考虑default bin,同样的,cross coverage也不考虑default。default sequence用于替代没有被显式定义的transition bins中指定的其它transition值。defualt或者defualt sequence bin不能被显式ignored。如果一个bins被指定为ignore_bins且被指定为default或defualt sequence,那么会报错的。

Wildcard bin使得所有的X、Z或?可以被当作0或1。如下:

wildcard?bins g12_15 = {?4'b11?? };

如果采样值有1100、1101、1110和1111,那么g12_15命中的次数就增加。

Wildcard bins也可以用于separate bins,例如:

wildcard?bins g12_15_array[] = {?4'b11?? };

上述会创建1100、1101、1110和1111这4个bin。

Wildcard bins也可以用于transition bins,例如:

wildcard?bins T0_3 = (2'b0x =>?2'b1x);

每当有下面的value transitions,T0_3 bin的计数会增加,有点类似于(0,1=>2,3)方法。

00?=>?10、00?=>?11、01?=>?10、01?=>?11

3.1. Transition bins的指定方式

value1(range_list1) => value2(range_list2):表示value1的下一次sample要是value2;如果有用到range_list,那么SV会拓展range_list里的值其它值进行转换,比如:

1,5?=>?6,?7

那么它的效果相当于:( 1=>6 ), ( 1=>7 ), ( 5=>6 ), ( 5=>7 )

trans_item [* repeat_range ]: 表示trans_item要重复repeat_range次,比如:

3?[* 5]

上述等价于:3=>3=>3=>3=>3

还可以指定重复的范围,比如:

3?[* 3:5]

上述等价于:( 3=>3=>3 ), ( 3=>3=>3=>3 ), ( 3=>3=>3=>3=>3 )

trans_item [-> repeat_range],或trans_item [= repeat_range]:表示trans_item出现个数,中间不管有什么其它值。比如:

3?[-> 3]

上述等于:...=>3...=>3...=>3,(...)代表任何不包含值为3的转换。在比如:

1?=>?3?[ ->?3] =>?5

上述等于:1...=>3...=>3...=>3 =>5

4、cross coverage

Coverage group可以指定在两个或多个coverpoints或变量之间进行cross coverage。如果指定的是变量,那么SV会隐式地帮它定义一个coverpoint,然后再参与到cross。因此cross coverage的输入本质上只有coverpoint。另外expression不能直接用于cross中,只能先将expression定义成coverpoint,然后再用cross。

Cross coverage提供了一个可选的label,该label会为cross中定义的bins创建一个层次化范围。Cross coverage也可用iff来选择是否在该次统计coverage。

对于coverpoint中定义为default、ignored或illegal的bins,在cross中不会创建bins的。Cross coverage只允许用同一个coverage group中的coverage points进行cross,引用其它group的coverpoint将会导致编译错误。

除了cross自动生成的bins之外,SV允许用户定义指定的cross coverage bins。可以使用bin select 方式来定义用户自定义的bins。用户自定义cross bins和自动生成 bins可以在同一个cross中生成的。只要没有被用户定义的cross bin截断的其它自动生成bins都会保持。如下例子:

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

x1 cross的结果为:

<i[0],j[0]><i[1],j[0]><i[0],j[1]><i[1],j[1]>

x2 cross的结果为:

i_zero ?// user-specified bin for <i[0],j[0]> and <i[0],j[1]><i[1],j[0]> ?// an automatically generated bin that is retained<i[1],j[1]> ?// an automatically generated bin that is retained

binsof语法产生它里面表达式的bins,该表达式可以是coverage point(显式)或单个变量(隐式生成coverpoint),或coverpoint bin。生成的结果bins可以进一步选择,通过intersect语法来选择或排除某些bins的值。Bins值的选择可以使用逗号分隔来选取多个,因此可以选择1个value、一个范围value、也可以范围值。例如:

[ $ :?value?]?=>?The?set?of?values?less than?or?equal?to?value[?value?: $ ]?=>?The?set?of?values?greater?or?equal?to?value

bins的选择可以和其它bins的的选择进行逻辑运算(&&, ||)来进一步选择的。

5、coverage option

Coverage options可以用于控制covergroup、coverpoint和cross的行为。有两种options类型:一种用于指定covergroup instance的行为,另一种用于指定covergroup type的行为。如果对于同样option,指定多个值会报错的。

5.1 Covergroup instance options

下表为instance-specific covergroup options及其描述。这些options可以在初始化instance-specific options时指定不同的值。这些初始化option value只影响对应的instance。

Instance-specific options可以在covergroup定义的时候set进去。在covergroup定义时设置这些options的语法如下:

option.member_name?= expression;

每一个covergroup、coverpoint或corss内部都自带有option这个成员变量。covergroup定义时,内部的option赋值语句是在该covergroup例化时生效的。per_instance和get_inst_coverage options只能在covergroup定义时设置。auto_bin_max和detect_overlap options只能在covergroup和coverpoint定义时生效。其它的instance-specific options可以在covergroup例化之后,通过赋值来设置的。下表总结了instance options在不同语法层次(covergroup、coverpoint或cross)的总结。所有的instance options可以在covergroup层次指定。除了weight、goal、comment和per_instance options,所有其它options在covergroup设置后,也作为该covergroup内部所有coverpoints和crosses的相应options的默认值。当然独立的coverpoints或crosses可以覆盖这些默认值。weight、goal、comment和per_instance options在covergroup层次设置时,不会影响更低层次(coverpoint和cross)相应options的默认值。

5.2 Covergroup type options

下表列出的options描述covergroup type整体的属性。它们就像是class中的static data members一样,对于所有的instances都起作用的。

上述提到的covergroup type options可以在covergroup定义时设置,语法如下:

type_option.member_name?= constant_expression;

type_option是每个covergroup、coverpoint和cross内建的static 成员。不同instances不能对type_options赋不同的值。这些options只能在初始化时通过常数表达式来设置。Strobe type option只能在covergroup定义时设置,其它type options可以在仿真进行中赋值,通过::方式来的。如下:

covergroup?gc?@(posedge clk) ;? ? a : coverpoint a_var;? ? b : coverpoint b_var;endgroup...//?Set?the comment?for?all covergroups of?type?"gc"gc::type_option.comment =?"Here is a comment for covergroup g1";//?Set?the weight?for?coverpoint?"a"?of all covergroups of?type?gcgc::a::type_option.weight =?3;gc?g1 = new;

下表列出了不同层次的type options可以是否被设置。covergroup层次的设置不影响到底下层次的设置。

6、coverage method

covergroup提供了一些coverage方法,这些方法可以在任何时刻被调用:

get_coverage()返回type coverage,它包含了所有该type例化出来的coverage累积,它是static方法,可以用::操作符和.操作符来引用。get_inst_coverage()返回指定instance的coverage,它只能对应的instance有关联,不是static方法,因此只能用.操作符。另外,covergroup里的sample()函数其实可以使用with关键字来override的。

SV提供了以下的系统方法去帮助管理覆盖率数据收集:

$set_coverage_db_name ( filename ):设置覆盖率数据库的文件名,在仿真运行结束时将覆盖率信息保存到该数据库中。

$load_coverage_db ( filename ):从给定的文件名加载所有coverage group类型的累积覆盖率信息。

$get_coverage ( ):返回0~100范围内所有coverage group类型的总体覆盖率的实数。这个数字是按照前面描述的方法计算的。

7、coverage computation

关于覆盖率的计算,请看这篇文章《Systemverilog覆盖率的合并和计算方式》。

相关推荐

登录即可解锁
  • 海量技术文章
  • 设计资源下载
  • 产业链客户资源
  • 写文章/发需求
立即登录