在SystemVerilog中提供了大量的用于获得coverage的方法,方便了用户进行功能覆盖率的收集,比较常见的主要有:$get_coverage、get_coverage和get_inst_coverage,那么这几种get coverage得到的到底是什么coverage彼此之间有什么差异呢?在SystemVerilog中关于这三个方法的描述如下:

ü $get_coverage:用来获取当前测试平台总体覆盖率,其值由所有的covergroup类型的覆盖率决定;

ü get_coverage:用来获取当前实例所对应的covergroup的覆盖率;

ü get_inst_coverage:用来获取当前covergroup实例的覆盖率;

文字描述有时候很苍白无力,那么这三个方法,在具体使用时具体区别在哪里呢,下面将通过示例说明这些方法的使用。

1 $get_coverage

【示例】 

【仿真结果】

示例中,covport0和covport1分别进行了例化,covport0的覆盖率为66.67,covport1的覆盖率为72.22,这两个covergroup在定义时指定了其在总体覆盖率中所占权重分别是:covport0的weight为2,covport1的权重为3,再结合covport0和covport1的覆盖率,我们可以得到总体覆盖率为70,即((72.22*3 + 66.67*2))/5。这里需要注意,在covergroup定义的时候,可以在其中通过type_option.weight设置该covergroup的覆盖率在总体覆盖率中的占比,当然我们也可以对weight不进行设置,如下例。

【示例】 

【仿真结果】 

示例中,两个covergroup定义的时候都没有指定其在总体覆盖率中的权重分布,此时将会采用默认的权重分配,即两个covergroup权重分别为1,得到的总体覆盖率为69.44,期(66.67*1+72.22*1)/2,这里需要注意,示例中没有指定weight时默认权重为1,并不是0,如果设置为0,那么我们得到的结果如下。

【示例】 

【仿真结果】

示例中,两个covergroup定义的时候指定其在总体覆盖率中权重分布均为0,即此时两个covergroup的覆盖率不会统计到总体覆盖率中,所以将每个covergroup中的权重分布设置为0和不进行设置是不一样的。同时,通过上述示例,我们可以看到如果要改变covergroup在总体覆盖率中的权重,需要在每个covergroup定义的时候指定不同的weight实现,并且需要通过type_option.weight指定。

2 get_inst_coverage

【示例】 

【仿真结果】

示例中,在covergroup中的每个coverpoint中设置了参数化的weight,这些参数来自于covergroup的每次实例传入的参数。对covergroup创建了三个实例,并且通过get_inst_coverage获得了三个实例各自的覆盖率,覆盖率分布如上图所示。并且可以看到使用get_coverage和get_inst_coverage是不同的,get_coverage获得的是covergroup的覆盖率,并不受covergroup实例覆盖率情况的影响,而get_inst_coverage获得的是covergroup每个实例的覆盖率。同时通过仿真结果我们还能够看到,通过设置了不同的coverpoint的weight,从而导致covergroup的每个实例的覆盖率分布不同,这主要是用因为每个covergroup实例中每个coverpoint的weight设置不同导致的,可见,在coverpoint中的权重设置影响到的是coverpoint在当前covergroup的覆盖率权重分布情况。

那么,如果我们对coverpoint和covergroup都通过option设置不同的weight,那么覆盖率分布情况又会如何呢?

【示例】

【仿真结果】

示例中,covergroup中通过option.weight在covergroup层面设置了权重weight,权重值来自于covergroup形参,当covergroup每次实例化时传入对应的值。在cv0中该weight值为3,cv1中为2,cv2中为2,通过仿真结果可以看到,该设置值并没有影响到总体covergroup的覆盖率。但是总体实例的覆盖率是受到该option.weight设置的影响,示例中总的实例覆盖率为60.04((58.33*3+61.11*2+61.64*2)/7),并且通过每个covergroup实例调用get_inst_coverage可以得到每个实例的覆盖率情况。

3 get_coverage

【示例】 

【仿真结果】

示例中,covport声明了三个变量cv0、cv1和cv2,通过这三个变量分别调用get_coverage()获取到的覆盖率相同,并且与总体覆盖率相同,可见同一类型的covergroup实例化后调用get_coverage获取的值相同,即get_coverage()获取的是当前变量类型的覆盖率。那么示例中为什么会出现使用get_coverage()获取的覆盖率与$get_coverage相同的情况呢?我们对比下面的示例了解其中不同。

【示例】 

【仿真结果】 

示例中,定义了两个covergroup,其中一个为具有参数的covergroup。根据这两个covergroup声明了三个变量cv0、cv1和cv2,其中cv1和cv2都是covport1类型,并且示例结果可以看到,虽然cv1和cv2传递的参数不同,但是cv1和cv2通过调用get_coverage()获取的覆盖率相同,而cv0因为来自于另一个covergroup,所以调用get_coverage()与cv1和cv2不同,并且示例中每个实例的覆盖率与$get_coverage()获得总体覆盖率都不相同,总体覆盖率来自于两个covergroup类型覆盖率,即(66.67*1+72.22*1)/2,可见通过get_coverage()获得的覆盖率是每个covergroup的覆盖率,不同的covergroup会根据其在总体覆盖率中的权重对总体覆盖率做出对应贡献。本小节开始处$get_coverage()和get_coverage()相同的原因是因为示例代码中仅定义了一个covergroup,所以此时通过$get_coverage获得覆盖率其实就是该covergroup的get_coverage()获得覆盖率。

通过上述示例,我们可以看到,对于大家关注的覆盖率的特点,在使用这些方法时,需要注意:

l 使用$get_coverage()获得的是当前设计中所有covergroup的覆盖率加权计算值;

l cg_name.get_coverage()获得的是当前变量的covergroup类型的覆盖率;

l 使用cg_name.get_inst_coverage()获得的是当前covergroup实例的覆盖率;

更多内容请关注下面公众号!图片

本文纯属学习之用,欢迎指正文中不足,封面图片若有侵权,请及时沟通!

 

更多推荐