功能覆盖率 | Systemverilog 笔记 8

Posted by Kion on January 23, 2020

功能覆盖率是衡量有多少设计特征已被测试的一个指标。

代码覆盖率是衡量有多少设计代码已被执行的一个指标。

下面给出功能覆盖率的简单例子。覆盖组与类相似,使用前需要实例化,若在类中定义,则可以直接用覆盖组的名字,否则要另起名字。一个覆盖组可以有多个测量点,且都同时测量。

program automatic test(busifc.TB ifc);
    class Transaction;
        rand bit[31:0] data;
        rand bit[2:0] port;
    endclass
/*创建覆盖组,测量覆盖率,tr.port*/    
    covergroup CovPort;
        coverpoint tr.port;
    endgroup
    
    initial begin
        Transaction tr;
        CovPort ck;
        ck = new();
        tr = new();
        repeat (32) begin
            assert(tr.randomize);
            ifc.cb.port<=tr.port;
            ifc.cb.data<=tr.data;
/*收集覆盖率*/
            ck.sample;
            @ifc.cb;
        end
    end
endprogram

采样的时候,SystemVerilog会把数据范围划分成小区域(仓),然后记录这些区域内的数据被捕获到的次数,进而计算覆盖率。如何划分区域涉及到覆盖率的准确与否。

/*可以使用auto_bin_max设置仓数*/
covergroup cp;
    coverpoint tr.port {
        /*分成两个仓*/
        options.auto_bin_max=2;
    }
endgroup

/*可以命名并自定义仓*/
covergroup cp;
    coverpoint tr.port {
        bins zero = {0};/*1个仓,0*/
        bins lo = {[1:3],5};/*1个仓,1,2,3,5*/
        bins hi[] = {[8:$]};/*8个仓,8:15*/
        bins misc = default;/*剩下的值*/
        /*另外,可以用ignore_bins排除不需要的范围
        用illegal_bins检查错误数据*/
    }
endgroup

/*可以为测量施加条件*/
covergroup cp;
    /*利用iff关键字,在未复位时测量*/
    coverpoint tr.port iff(!bus_if.reset);
endgroup

/*翻转覆盖率*/
covergroup cp;
    coverpoint tr.port {
        /*测量从0翻转到1及2的次数*/
        bins t1=(0=>1),(0=>2);
    }
endgroup

/*可以用start和stop函数控制覆盖组的启动*/
CovPort ck=new();
#1 ck.stop();
#1 ck.start();

交叉覆盖率是分析多个测量点耦合的覆盖率。一个点有n中取值,另一个点有m种取值,则它们交叉后有n*m种取值,交叉覆盖率研究的就是这n*m的组合。同样可以用bin,ignore_bins来为交叉覆盖率(cross point_a,point_b)划分仓。

covergroup CovPort;
    kind:coverpoint tr.kind{
        option.weight=5;/*设置在总体中的权重*/
    }
    
    port:coverpoint tr.port;/*可以添加覆盖点标识*/
    /*交叉覆盖率*/
    cross kind,port{
        ignore_bins hi=binsof(port)intersect{7};/*排除port中包含7的仓*/
        ignore_bins md=binsof(port)intersect{0}&&binsof(kind)intersect{[9:11]};
        ignore_bins lo=binsof(kind.lo);/*排除kind的lo仓*/
    }
    
endgroup

可以令覆盖组更加灵活。

/*传递数值*/
covergroup covport(int mid);
    coverpoint port{
        bins lo ={[0:mid-1]};
        bins hi ={[mid:$]};
    }
endgroup
/*调用*/
covport cp;
cp=new(5);
/*传递要覆盖的参数*/
covergroup covport(ref bit[2:0]port, input int mid);
    coverpoint port{
        bins lo = {[0:mid-1]};
        bins hi = {[mid:$]};
    }
endgroup
/*调用*/
covport cpa, cpb;
cpa = new(port_a,4);
cpb = new(port_b,5);