功能覆盖率漫谈

以下内容均以使用vcs工具为前提。

(一)跨group交叉覆盖率

vcs支持跨covergroup交叉覆盖率,意味着:

interface cov_if;
    logic a;
    logic b;
    logic c;
endinterface

class coverage;
    virtual cov_if cov_port;

    covergroup cg_a;
        option.per_instance = 1;
        cp_a : coverpoint cov_port.a;
    endgroup

    covergroup cg_b;
        option.per_instance = 1;
        cp_b : coverpoint cov_port.b;
        cp_c : coverpoint cov_port.c;
    endgroup

    covergroup cg_axb;
        option.per_instance = 1;
        cx_a_b : cross cg_a.cp_a, cg_b.cp_b;
        cx_a_c : cross cg_a.cp_a, cg_b.cp_c;
    endgroup

    function new ();
        cg_a = new();
        cg_b = new();
        cg_axb = new();
    endfunction : new

    function void sample ();
        cg_a.sample();
        cg_b.sample();
    endfunction : sample
endclass : coverage

是可以跑起来的,书写上的便利可以让组合更自由。这种写法有几个地方要注意:

1.需要在vcs elaborate时加上-lca(limited customer availability)选项。

2.上述covergroup只能写在class里, 作为全局的covergroup就无法使用该功能。

3.cov_axb只需要new即可,会自动sample,如果同时调用cg_a, cg_b, cov_axb的sample会报warning:Warning-[FCPSHCG] Sampling hierarchical covergroup.Procedural sampling of hierarchical covergroup instances will be ignored.


(二)covergroup option/type_option

  很多时候我们只看到书上那么写,别人那么用,却很少关注为什么要这么写。下面从最常见的一些开关开始介绍:

(1) per_instance

  默认的时候这个选项是0,是关闭的。instance,指covergroup的instance, 如果这个开关打开,那么每一个instance的覆盖率会被列出,否则只能看到一个综合的结果。这里问题来了,什么时候需要有多个covergroup的instance?答案是需要复用的时候。假如说系统中有两个一模一样的port, 需要对他们都进行覆盖率采样分析,那么完全可以之写一个covergroup, 实例化两次,传入不同的port.还是以上面的例子为例,这一次加入驱动的细节:

module top;
	coverage 	cov0;
	coverage 	cov1;
	cov_if 		cov_port0();
	cov_if 		cov_port1();

	initial begin
		cov0 = new();
		cov0.cov_port = cov_port0;
		cov_port0.a <= 1;
		cov_port0.b <= 0;
		cov_port0.c <= 0;

		cov1 = new();
		cov1.cov_port = cov_port1;
		cov_port1.a <= 1;
		cov_port1.b <= 1;
		cov_port1.c <= 1;
		#20;
		$finish;
	end

	always #1 cov_port0.a = ~cov_port0.a;
	always #2 cov_port0.b = ~cov_port0.b;
	always #1 cov_port0.c = ~cov_port0.c;
	always #1 cov0.sample();
	always #1 cov_port1.a = ~cov_port1.a;
	always #2 cov_port1.b = ~cov_port1.b;
	always #1 cov_port1.c = ~cov_port1.c;
	always #1 cov1.sample();
endmodule : top
会看到这样的波形:

功能覆盖率漫谈_第1张图片

port0中a和c完全反相,而port1中则完全同相,这个时候cross a,c,两个port都会各有两种情形覆盖不到,而他们的总和,却是四种情况都覆盖到了。如果加了per_instance参数,那么我们看到的报告会包含下面这两个部分:

功能覆盖率漫谈_第2张图片功能覆盖率漫谈_第3张图片功能覆盖率漫谈_第4张图片功能覆盖率漫谈_第5张图片

否则只能看到一个总的部分:

功能覆盖率漫谈_第6张图片


(2) goal

预期的目标,会作为分数计算的依据,具体见LRM的公式。

功能覆盖率漫谈_第7张图片

这里特别注意type_option与option的区别,type_option会影响最后总和的结果,而option影响的是每个intance内的结果。这一点对于weight, comment等其他参数也一样。


(3)name & comment

这里指instance的name

功能覆盖率漫谈_第8张图片

group instance后的名字

comment也有相应的标示


(4)type_option.merge_instances

将所有的instence的hit情形合并到一起,例如inst1 hit了0个,inst2 hit了全部,那么分数就会是100.如果不打开此选项,则计算instence的加权平均分。这个选项vcs不支持。


(5)distribute_first

vcs还是不支持,想要自定义bin的顺序目前看来是不可能了,但是with语法还是可以部分支持的。

你可能感兴趣的:(vcs,SystemVerilog)