【项目实战】功能覆盖率的收集1

发布时间:2024年01月08日

功能覆盖率的收集


目录

功能覆盖率的收集

1. 背景知识

1.1 概念

1.2 启动

1.2.1 自动trigger

1.2.2 sample

?1.3 covergroup

?1.3.1 coverpoint

1.3.2 cross

1.3.3 bins

1.3.3.1 scaler bins

1.3.3.2 vector bins

1.3.3.3 transitions bins

1.3.3.4 wildcard bins?

1.3.3.5 ignore bins

1.3.3.6 illegal bins

2 脚本工具使用

2.1 表格格式

3 IMC


五星上将麦克阿瑟说过:这篇文章通俗易懂,我很欣赏!


1. 背景知识

1.1 概念

首先要理解什么是功能覆盖率?功能覆盖率的代码是不是需要我们手写?代码覆盖率已经100%了,功能覆盖率还需要再验证?等等问题,都是我们第一次接触这个概念会遇到的。

功能覆盖率是一种比例数据,指芯片中已验证通过的功能占该芯片全部功能的百分比,验证工作的目标就是尽量使功能覆盖率达到100%.功能覆盖率与verification point有一些类似,也可以认为是把verification point里的feature分别写成一个个的coverpoint/cross。与verification point不同的是功能覆盖率能有效的知道已验证的功能的百分比,verification point是人工管理,比较容易出错,而且也不能保证某一条已经完成的feature是真实有效的测试到了(因为没有数据支持)。

换句话说,每一个功能点对应的场景是多种多样的,我们需要考虑到当某个特定条件满足时的所有场景。这就是功能验证的意义。代码覆盖率就好比一张平面,只要每行的代码能够覆盖就行。功能覆盖率更像是一个立体。我们需要每一个随机的验证用例可以覆盖到空间中的每一个粒子。

通常,功能覆盖率不需要我们手写!通过EXECL中填写的关键信息,通过脚本,转化成最终我们需要的sv文件。

接下来,我将对这些细节详细的展开叙述。

1.2 启动

功能覆盖率以covergroup为一个群体单元,一个covergroup里包含了所测模块的部分或者全部的功能点,一个block可以有一个或者多个的covergroup。

一个covergroup 可以自动trigger,也可以用户自己决定什么时候trigger.

1.2.1 自动trigger

covergroup test
    (@posedge clk){
        coverage specification
    }
endgroup:test

test cg_inst
cg_inst = new()

倒数2行创建一个covergroup的实体,创建之后,第2行在clk的上升沿就会去收集这个covergroup的覆盖率数据。

1.2.2 sample

covergroup test
    coverage specification
endgroup:test

test cg_inst
cg_inst = new()

forever begin
    repeat(10) (@posedge clk);
    cg_inst.sample();
end

在covergroup里没有启动条件,forever 就是用户自定义的启动条件,每过10个clk就收集一次覆盖率数据。

我们在收集覆盖率数据的时候尽量不要用clk的沿作为启动条件,虽然这样收集的次数会很多,保证数据不会遗漏,使得最终的结果很完美。但是,缺点也很大!因为每个clk的收集,会极大的影响我们的仿真效率,拖垮仿真时间。通俗的理解,现在有一个32bit位宽的计数器,如果每个clk采集一次数据的话,一个验证用例你要跑几天几夜的时间。那几百个case同时跑,服务器无奈的摇摇头,五星上将麦克阿瑟无奈的摇摇头。

那么应该怎么做才合理呢?

一般我们可以把covergroup分为静态的动态的

  1. 1 静态的covergroup在配置完成之后就可以sample,里面的功能点是仿真刚开始的时候就确定好了,仿真过程中几乎不会改变,这样一次sample就可以把我们想要的数据都收集完毕,完全没必要一直重复的去收集。
  2. 2 动态的covergroup一般是针对数据通路,在仿真过程中一直在变换,我们要权衡启动条件,尽可能的保证数据不遗漏(即使数据遗漏也没关系,顶多就是某一个coverpoint或者cross可能case已经跑到,但是因为收集的次数不够而导致报告没有覆盖到,我们再造一个定向case就可以了,但是如果说每次跑regression都去重复不断的去收集这个covergroup里的功能点,regression的时间可能是不收集功能覆盖率的几十倍甚至上百倍,这样就得不偿失了),也要保证我们的仿真时间跟不收集覆盖率的时候不要差别太大。

1.3 covergroup

covergroup里一般包含coverpointcross,coverpoint和cross里又包含bins

?1.3.1 coverpoint

一个coverpoint一般是对某个变量的描述,如该变量的最大值/最小值,某些特定值是否能cover等。当然两个变量的比较关系也是一种特殊的coverpoint。

1.3.2 cross

每一个1bit的变量,取值都会是0和1,这也就是代码中出现AUTO的原因。

//该覆盖率组命名为test_cov_cg
covergroup test_cov_cg;
    option.name = "test_cov_cg";
    //变量sa_en的coverpoint
    cp_sa_en: coverpoint cfg.test_cfg.sa_en iff(sample_cp_sa_en) {
        type_option.weight =2;
        //分为两个bins(仓),分别为0和1
        bins bin_0 = {0}; // AUTO
        bins bin_1 = {1}; // AUTO
    }
    
    //变量test_mode的coverpoint
    cp_test_mode: coverpoint cfg.test_cfg.test_mode iff(sample_cp_test_mode){
        type_option.weight = 2;
        //分为四个仓,分别为0/1/2/3
        bins bin_0 = {0}; // AUTO
        bins bin_1 = {1}; // AUTO
        bins bin_2 = {2}; // AUTO
        bins bin_3 = {3}; // AUTO
    }
    
    //sa_en和test_mode的cross可自定义仓,也可以ignore某些仓
    cs_cp_sa_en_cp_test_mode: cross cp_sa_en, cp_test_mode{
        type_option.weight =2;
        bins bin_cp1_1 = binsof(cp_sa_en) intersect {1};
    }
endgroup

同样的,两个不同的变量也可以组合起来使用,就是cross。可以很明确的说,这些代码不用我们自己写。后面我会详细的介绍。

1.3.3 bins

1.3.3.1 scaler bins
bins r0 = {0,13,64}
bins r1 = {[10:$]} // 10 to MAX
1.3.3.2 vector bins
bins r[] = {0,13,64} // r[0]= 0/r[1]=13/r[2]=64
1.3.3.3 transitions bins

    bins a =(1=>2)
	bins b=(1=>2=>3)
	bins c=(1,5=>6,7) //1=>5 or 1=>7 or 5=>6 or 5=>7
	bins d={3[*3]} // 3=>3=>3
	bins e=(4=>5),([7:9],11=>12) //4=>5 or 7/8/9/11=>12
	bins f[]=(4=>5),([7:9],11=>12) //自动分为很多仓

1.3.3.4 wildcard bins?

只关注最低2bit位,其余的bit位是0是1都可以接受。

wildcard bins a ={7'b?????01}; 
1.3.3.5 ignore bins

    //忽略1/2/3
	bins legal={[0:15]}
	ignore_bins ignore ={1,2,3}
1.3.3.6 illegal bins
illegal_bins a ={4=>5} //出现4=>5平台会报error

2 脚本工具使用

功能覆盖率代码有一定的格式,本着手动写既浪费时间又容易出错的原则,所以自动产生func_cov的代码很有必要。把功能点写到Excel表格里,用一个脚本自动产生对该Excel表格的功能覆盖率代码。这便是我们后面章节重点要说的内容。通过第一张的内容,我们只需要理解功覆盖率文件中的一些语法即可,接下来就是如何用脚本生成代码的事情了。

2.1 表格格式

下面这幅图只是简单的说明。

TYPE第一列:选择是coverpoint还是cross

VARIABLE第二列:选择是变量

BITS第三列:是位宽

QTY第四列:针对的是数组

NAME第五列:信号名,excel自动生成

BINS第六列:BINS,填写我们关注的场景

CP1/CP2/CP3...主要用在CROSS这种情况中

下面将介绍一些常用到的一些场景

Coverpoint BINS

类型说明例子
AUTO自动拆分为2的位宽个bins

cp_var_a:coverpoint var_a{

? ? ? ? bins bin_0 = {0}; // AUTO

? ? ? ? bins bin_1 ={1}; // AUTO? ? ? ??

}

MIN有MIN和MIN=xx两种 情况, MIN=xx支持10进制和16进制,如果只写MIN,那么MIN=0

MIN = 8'ha =>?

bins bin_min = {8'ha}; //MIN

类型说明例子
MAX

有MAX和 MAX=xx两种情况,MAX=xx支持10进制和16进制,

如果仅写MAX,那么MAX=2位宽-1

MAX=200?? =>

bins bin_max = {8'hc8};? //MAX
LOWMIN和MAX取中间,中间偏左的为LOW(不包含MIN)

MAX=8'hAA,MIN=10,LOW? =>

bins bin_min = {8'ha};? //MIN

bins bin_max = {8'haa}; //MAX

bins bin_low = {[8'hb:8'h5a]}; //LOW
HIGHMIN和MAX取中间,中间偏右的为HIGH(不包含MAX)

MAX=8'hAA,MIN=10,HIGH? =>

bins bin_min = {8'ha};? //MIN

bins bin_max = {8'haa}; //MAX

bins bin_high= {[8'h5b:8'ha9]}; //HIGH

Cross BINS:

类型说明例子
ONLY不关心自动cross的结果,只考虑ONLY里的仓
IGNORE在自动cross的基础上,exclude掉部分仓

3 IMC

需要用到 Cadence IMC?

首先导入代码覆盖率文件。

?

?第二步: 打开功能覆盖率选项

结果如下图所示:

虽然我打开了代码覆盖率的total文件,但是功能覆盖率我同样也已经覆盖了,所以只需要切换一下选项即可。这里要说的是,如果你的功能覆盖率没有达到100%,可以添加一些定向的case到验证环境中。

举个例子:

下面的功能覆盖率只有75%,为什么呢?因为最小值0,没有覆盖到。

假设这个信号叫做counter_sig,8bit 位宽。它的BINS是【MIN, LOW, HIGH,MAX】

那么1~7F, 7F~FE, FF这三种情况都覆盖到了,但是当counter_sig=0 (MIN)却没有覆盖到。

存在的原因有2中:你的验证用例功能的不完善;或者是你的随机的次数太少,没有覆盖到这种情况。通常都是后者导致的,所以要是收集代码覆盖率的时候,可以让随机的次数多一些,结果会理想的很多。

脚本的介绍将会在以后的文章中提到!欢迎大家随时讨论交流!

?

文章来源:https://blog.csdn.net/TommiWei/article/details/135449886
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。