综述

标准上对Func_coverage的定义是:
Functional coverage is a user-defined metric that measures how much of the design specification, as enumerated by features in the test plan, has been exercised.
个人理解:
衡量验证激励完备性及场景完备性的一个标准,Functional_coverage可以检查
1. 你关心的场景是否覆盖
2. 构造的随机激励的随机程度
3. 对应的feature点是否有覆盖
Functional_coverage与code coverage不同. Code coverage 由工具自动产生, Functional coverage是验证工程师基于对DUT的认识来对验证feature进行分解后,将需要覆盖的点进行分析后写出。 因此对于DUT的认识非常重要。

Functional_coverage可以检查:

1. 你关心的场景是否覆盖完备;2. 验证工程师构造的随机激励的随机程度/合理性;3. 从Spec中提取的feature点是否覆盖完备;...

Function Coverage通过编写coverage group, coverage points和bins等来构造收集“容器”。这里我们不介绍Assertion Coverage, Code Coverage等,以后会单独介绍。

收集Function Coverage的相关验证文件是由验证工程师定义编写的,灵活度很高,所以更需要谨慎对待,这是个Review的过程,一般需要编写:unit_coverage.sv + unit_coverage_interface.sv + top.sv。

1. unit_coverage.sv (unit_cov.sv),可能包含多个功能覆盖模型coverage group,构造的收集“容器”,收集过程在这里实现;2. unit_coverage_interface.sv(unit_cov_if.sv),定义unit_cov.sv中需要用到的interface;3. top.sv,将unit_cov_if.sv中定义的interface与DUT中对应的interface连接起来;

一、实现

功能覆盖率模型/覆盖组(cover group):

覆盖组是使用cover group构造定义的。

覆盖点(cover point):

覆盖点是使用cover ponit和bins构造定义的。

        一个覆盖组可以包含一个或多个覆盖点。每个覆盖点都与“ bins”关联。“bins”可自动创建,也可以明确定义。

        SystemVerilog是一名芯片验证工程师,必须掌握的一门语言,其中Function Coverage是必须要懂的知识点之一;

看完这篇,应该就会写Function Coverage了;

一、概述

有一定基础,想直接看用法,直接看第二部分——实现(强调!代码部分要精读,文字略抽象,例子好理解)。

功能覆盖率(Function Coverage)是衡量验证完备性的重要标准之一。

其用于度量验证中已执行的测试点(cover point)占设计规范的比例,从而避免功能验证的遗漏。或者说,Functional coverage是验证工程师基于对DUT的认识来对验证feature进行分解后,将需要覆盖的点进行分析后写出,因此对于DUT Spec的信息提取非常重要。

Functional_coverage可以检查:

1. 你关心的场景是否覆盖完备;2. 验证工程师构造的随机激励的随机程度/合理性;3. 从Spec中提取的feature点是否覆盖完备;...

Function Coverage通过编写coverage group, coverage points和bins等来构造收集“容器”。这里我们不介绍Assertion Coverage, Code Coverage等,以后会单独介绍。

收集Function Coverage的相关验证文件是由验证工程师定义编写的,灵活度很高,所以更需要谨慎对待,这是个Review的过程,一般需要编写:unit_coverage.sv + unit_coverage_interface.sv + top.sv。

1. unit_coverage.sv (unit_cov.sv),可能包含多个功能覆盖模型coverage group,构造的收集“容器”,收集过程在这里实现;2. unit_coverage_interface.sv(unit_cov_if.sv),定义unit_cov.sv中需要用到的interface;3. top.sv,将unit_cov_if.sv中定义的interface与DUT中对应的interface连接起来;

二、功能覆盖率模型/覆盖组(cover group):

覆盖组是使用cover group构造定义的。

ex1: 会在指定的signal_abc变化时才采样

wKgZomR8TDGAc0leAADkFCfty84581.jpg

ex2:在时钟上升沿((posedge)采样。

覆盖点(cover ponit):
 

wKgaomR8TJqAbM2cAACJGNmh7Ug700.jpg

覆盖点是使用cover ponit和bins构造定义的。

一个覆盖组可以包含一个或多个覆盖点。每个覆盖点都与“ bins”关联。“bins”可自动创建,也可以明确定义。

ex1:自动创建bins

为coverpoint变量范围的每个值自动创建一个bins,这称为自动或隐式bins。

对于“ n”位的整数coverpoint变量,将创建2^n个bin,但是最多为64个,当2^n大于64时,每个bin不再是一个值,而是2^n/64

ex2:明确定义bins

该方式--- 常用,这里重点看每个bins定义代表的不同意义。

在覆盖点标识符(cover point)之后,在大括号{}中显式声明bins,其中声明bins名称和变量值/范围。

ex3:交叉覆盖(cross)

三、覆盖选项(cover options)

        每个bins的最小匹配/采样次数。默认值为“ 1”,默认情况下,数值采样了1次就可以计入有效的bin(已覆盖)。可以通过修改at_least来修改每个bin对应的最小采样次数,注意,如果低于at_least数值,则该bin不算被覆盖。在covergroup里使用 option.at_least,会影响所有的coverpoint里的bin。在coverpoint里使用 option.at_least,只影响该coverpoint下的bin,但coverpoint中使用会覆盖covergroup中的使用。

auto_bin_max

没有为coverpoint明确定义bins时自动创建bins的最大数量。默认值为“ 64”。

cross_auto_bin_max

没有默认值,它是无界的。

        如果对一个covergroup实例化了很多次,那么SV默认会把所有实例的覆盖率合并在一起。 option.per_instance = 1,表示covergroup的每一个实例的覆盖率都要单独计算。

goal

        不论covergroup或是coverpoint的目标覆盖率皆是100%,不过也可以通过option.goal=value,来降低覆盖率目标,这个选项只会影响覆盖率报告。

Covergroup定义与收集
Covergroup定义与例化
        Covergroup是承载coverage的容器。 coverage只能收集integral Data types,对于real等类型的数据是不能收集, 附:integral data type。


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

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

        

四、Coverage的sample


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

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
 

  1. 使用clocking event进行触发, @(expression), 这里的expression通常为 event,posedge clk, singal等,在这里expression值发生变化便会触发采样(如果是@(singal), signal的值发生变化及采样)。

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 不采样
 

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐