SystemVerilog covergroup语法小结

2 篇文章 9 订阅

目录

一、Covergroup定义与收集

 1. 1 Covergroup定义与例化

 1.2 Covergroup可以定义在何处

  1.3 参数化的covergroup

 1.4 采样

二、coverpoint

 2.1 coverpoint定义

 2.2 Bins for values

 2.3 SystemVerilog-2012 中新增特性

2.4 bins的种类

一、Covergroup定义与收集

 1. 1 Covergroup定义与例化

Covergroup是承载coverage的容器。 coverage只能收集integral Data types,对于real等类型的数据是不能收集的。

 1.2 Covergroup可以定义在何处

Covergroup只能定义在package/class/module/program/checker/interface中。

covergroup的定义与例化

covergroup demo_cg();  
  ... 
endgroup : demo_cg
 
demo_cg    test_cg_inst = new;
 
 
demo_cg    test_cg_inst[4];  //Error: Arrays of covergroup instances are not supported.
demo_cg    a_inst, b_inst; 
 
a_inst = new; 
b_inst = new;     // OK

这种方式可以例化多份,但注意covergroup 不能例化为数组(此方式只有Xcelium不支持)

  1.3 参数化的covergroup

Covergroup可以传入参数,端口类型的话只可以的input/ref, Output与inout是不支持的。定义为input的变量在例化时便定义好了,后面该变量变化,Covergroup内的值不会随着变化,如果需要采集变化的变量,需要定义为ref类型。

class test;
    int port_a,port_b;
 
    covergroup demo_cg(ref int cnt, input int mid) @(posedge clk);
        counter_cg: coverpoint cnt{
          bins part1[] = {[0:mid]};
          bins part2[] = {[mid+1:10]};
        }
      endgroup : demo_cg
 
      port_b = 5;
 
      demo_cg = new(port_a, port_b);  //这里demo_cg, mid为5
      ....
      port_a = 1;  
    
    @(posdge clk); //sample, port_a=1
    port_a = 2;
    port_b = 4;    //mid不在变化
    @(posdge clk); //sample, port_a=2
    ...
endclass

 1.4 采样

采集coverage的方式有很多,可以使用自带的sample函数,也可以使用 @来指定一个event。

使用sample采集
sample是Covergroup自带函数,可以调用sample来指定的采样对象,Sample可以被override,传入的参数可以作为采集的一部分。

Class test;
    logic[3:0]     port_a;
 
    covergroup demo_cg with function sample(bit[3:0] i);
        coverpoint i;
    endgroup
    ...
    port_a = 1;
 
    demo_cg.sample(port_a);
endclass

但注意 Sample传入的参数只能作为coverpoint、cross中需要采集的一部分, 其他的使用方式会报错:
使用event进行触发

int        port_a;
 
covergroup demo1_cg @(port_a == 1); 
endgroup
 
covergroup demo2_cg @(port_a, iff port_a == 1 ); 
endgroup
...
 
@(posedge clk); 
port_a = 1; //(port_a == 1)0->1, port_a 0->1, demo1_cg, demo2_cg都发生采样
 
@(posedge clk); 
port_a = 1; // (port_a == 1) 1->1无变化 port_a 1->1变化, demo1_cg, demo2_cg都不采样
 
@(posedge clk); 
port_a = 0; //(port_a == 1) 1->0发生变化, demo1_cg发生变化, port_a != 1 , demo2_cg 不采样

因此注意实际采样时,不要用这中条件表达式的形式来进行采样, 得到的结果往往超出你的预期。绿皮书中有采用 assert_porperty的方式进行采样,这里省略。
推荐采用指定event的方式,或者直接调用sample函数,这样清晰明确。

二、coverpoint

 2.1 coverpoint定义

Coverpoint定义了Covergroup具体需要cover的点,这个coverpoint的点可以是变量,或者变量的表达式,但数据类型注意依然必须是integral data types。另外coverpoint收集的变量需要在定义coverpoint前声明。 

real       tim;
 
covergroup demo_cg;
    coverpoint a;              //方式1,不指定coverpoint的label
    b_cp: coverpoint b;     //方式2, 指定label
    cb_cp: coverpoint c+b;
    tim_cp: coverpoint tim; // Error,不可以是non-integral data type
    d_cp: coverpoint d;     // Error, 应先定义 int d;
endgroup
 
.....
int d;

定义的两种方式, 指定label和不指定label,不指定label的话,系统自动将变量名作为label. 推荐指定label,加入_cp表明是coverpoint 清晰明了。
LRM中可以在coverpoint前定义数据类型,该coverpoint中的变量的数据类型会被强制转换成定义的数据类型。但Xcelium不支持,VCS可以尝试一下。

 2.2 Bins for values

Coverpoint中使用bins来收集每个coverpoint的变量具体值,bins可以用户自己指定,也可以系统自动产生。当用户自定义bins后,不在用户自定义的bins的范围内数值被自动归为default bins,default bins的值将不会建仓,default bins通常由系统自动产生,用户也可以自定义。bins可以cover 一个值/多个值,bins还可以指定为数组。
如果bins[fixed_number] = {x,y,…,z}; 如果fixed_number < {}中的数量,则每个子bins中的数量是他们的整除, 如果有余数,则放入最后一个bins中。

在bins中也可以使用iff(expression), 来限定采集的条件
 

bit[3:0] a,b,c;
 
covergroup demo_cg(input bit[3:0] mid);
    coverpoint a {
        bins zero         = {0};
        bins mult        = {0,[2:3]};       //当a为 0/2/3便可以cover该bins
        bins test1[13]  = {[1:10],1,4,7};  //test1被分为10个子bins,分别为<1> ... <10> <1> <4> <7>
        bins test2[20]  = {[1:10],1,4,7};  //test2虽然定义了20个子bins,但实际上被分成了13个子bins,<1> ...<10> <1> <4> <7>
        bins test3[4]   = {[1:10],1,4,7};  //test3分成了4个子bins,<1,2,3>, <4,5,6>, <7,8,9>, <10,1,4,7>,这里是个trick
        bins test4[]    = {[1:10],1,4,7};  //test4被自动分成了10个子bins,<1> ... <10>, 重复的被merge在一起了
        //这里default_bins 为<11> ...<15>,这些便不再建仓
    }
    coverpoint b {
        bins sml[] = {[1:8]} iff(c==1);   //在c==1时,才开始收集
        bins big[] = default;                //其他的<0>,<9>...<15>
    }
    c_cp: coverpoint c {
        bins sml[] = {[0:mid]};            //mid的值在covergroup new的时候给出来。
    } 
endgroup
...
demo_cg = new(5);                         //指定mid=5

 2.3 SystemVerilog-2012 中新增特性

with(with_cover_expression) 可以指定expression,对满足expression的值进行建仓
coverpoint a {
    bins test6[] = {[1:10]} with(item%3 == 0); //只对1~10范围内满足%3==0的数进行建仓,<3>,<6>,<9>
    bins test7[] = {[1:10]} with (myfunc(item)); //只对1~10范围内满足myfunc的值进行建仓
}

可以支持对自定义的数组进行建仓,这种常用再onehot、复杂算法场景中 。(select信号为onehot信号,cover在select信号所有有效的场景情况下,读写都有发生过。)

logic[5:0]   encoding[6] ;
logic[5:0]   select;
logic         rw; 
covergroup onehot_rw_cg;
    SEL: covergroup select{
        bins onehot[6] = encoding;        //这里onehot的每个子bins中都是有效的场景<6'b1><6'b10><6'b100> ... <6'b10_0000>
    }
    RW: coverpoint rw{
        bins WR = {1};
        bins RD = {0};
    }
    sel_rw_crs: cross SEL, RW; 
endgroup
 
foreach(encoding[i]) encoding[i] = 1<<i;  //encoding构造onehot数组 //需要在covergroup new之前定义好数组场景
onhot_rw_cg = new;
  bins for sequence : 反转覆盖率
Coverpoint a {
    bins test1         = (1=>2=>3);          //收集变量a 从1变化到2再变化到3的场景
    bins test2         = (1=>2), (2=>3);     //收集变量a 从1变化到2或者2变化到3的场景
    bins test3         = (1,2=>6,7);          //表示收集1=>6/2=>6/1=>7/2=>7 四种场景之一
    bins test4[]     = (1,2=>6,7);          //表示收集1=>6,2=>6,1=>7,2=>7 四种场景
    bins test5      = (1=>[*3]2=>3);     //收集1=>2=>2=>2=>3
    bins test6      = (1=>[*3:5]2);     //收集1=>3~5个2
    bins test7      = (1[->3]);            //收集...=>1...=>1...=>1 (...)表示任意数量的除1之外的任何值
    bins test8      = (1[=3]) ;         //收集...=>1...=>1...=>1 (...)表示任意数量的除1之外的任何值, 这个要求最后一个1结束后不会再出现任意1
    bins test9      = (1=>2[->3]=>3);   //收集 1...=>2...=>2...=>2=>3 
    bins test10     = (1=>2[->3]=>3);   //收集 1...=>2...=>2...=>2...=>3  
}


2.4 bins的种类

除了bins还有 illegal_bins和ignore_bins。

illegal_bins 表示当采集的值再illegal_bins内,属于非法值报错,

ignore_bins为不采集某些值。
优先级为: illegal_bins > ignore_bins> bins

coverpoint a {
    illegal_bins zero0 = {0};
    ignore_bins  zero1 = {0};
    bins         zero2 = {0};
    bins         one  = {1};
}

 
//结果: 当a=0时, 首先报错,然后在工具上不能看到bins zero2(被ignore掉)只能看到one

  • 8
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值