关于时钟模块完备性验证方法第八章-功能覆盖率

系列文章目录


第八章 功能覆盖率统计


文章目录

目录

系列文章目录

文章目录

前言

一、什么功能覆盖率?

二、使用步骤

1.自动化check代码代码如下:

总结



前言

      通过以上几个章节,我们介绍了关于时钟模块完备性验证的多个自动化checker,通过在testbench中添加以上自动化checker,可以自动检查出各种违例,假如说我们准备好了这些自动化checker,那么接下来就需要我们产生丰富的测试激励来对系统时钟进行验证。通常情况下代码覆盖率可以作为验证质量的一个衡量标准,但是很多时候,考虑到项目周期短,验证人员分配不足等各种先天因素的影响,我们很难把代码覆盖率收集到某个高度。但是有些功能是在项目tap out之前必须要保证的,尤其是对于时钟模块的验证,根据实际应用需求,各个模块的时钟方案较为明确,因此我们引入了功能覆盖率模型,通过建立通过覆盖率模型,来统计我们是否cover了所有所需的功能配置,当功能覆盖率全部被覆盖,且自动化checker又没有上报错误,即可在一定程度上说明设计已经具有一定的鲁棒性,这将大大增加我们tap out的信心。       

        按照前几个章节介绍的自动化checker,对时钟验证进行了分类,基本包括了时钟的反复开关,时钟的任意分频,以及时钟的固定次序分频这几个部分。其中时钟反复开关过程由时钟模块完备性验证方法第一章介绍的自动化进行把关。而对于时钟的分频,涉及到时钟模块完备性验证方法第二、三、四、五、六章节进行保证。主要因为在时钟切换过程中,除了要保证切换后的时钟频率是正确的,还有可能在切换过程中引入glitch,最小min pulse、相位不对齐、不定态、占空比以及strobe出现违例的可能。因为,为了保证时钟模块的验证完备性,不但需要丰富的测试激励,还需要与之匹配的一套完美的自动化验证checker,否则在大量的测试激励下,靠人眼去逐一check波形几乎是不可能的事情,尤其是项目进行中难免进行一轮又一轮的回归测试,在短期的回归测试周期内check完所有的验证结果,已经远远超过了人力范畴,必须要有一套完美的验证环境,才能做到不错过、不放过。当然,要想把这部分内容做到极致,仅仅参考这几个章节介绍的方法还是不够的,这些章节虽然是我在实战过程中遇到问题时,寻找的一些应对之策,但是随着问题的不断暴露,仍需要我们不断的更新方式方法,遇到问题,解决问题。

     不过整体来说这几个章节已经列出了常见的一些问题以及解决方法,可供大家参考。


提示:以下是本篇文章正文内容,下面案例可供参考

一、什么功能覆盖率?

       首先覆盖率基本上可以分为代码覆盖率和功能覆盖率,所谓代码覆盖率就是针对RTL代码的执行情况,验证工程师通过添加测试激励,通过工具来分析这些测试激励所激活的代码执行情况。而功能覆盖率一般是需要验证工程师根据特定的功能进行自定义。或者通过systemverilog assertion、或者通过coverpoint的方式,将一些我们关心的功能,转化为仿真工具可以识别的语言进行描述。同样的,功能覆盖率也是基于特定的测试激励,当对RTL添加测试激励后,一旦条件满足功能点,即表示命中,最后通过将所有测试激励产生的运行结果进行merge,生成最终的覆盖率报告。

      这里只是从概率上简单介绍了一些覆盖率,关于这两部分内容的详细介绍,可以参考《systemverilog与功能验证》这本书,由钟文枫编著。

二、使用步骤

1.自动化check代码代码如下:

举例:假如我们对以下两个时钟的门控使能进行功能覆盖率建模:

covergroup clk_en_cfg @(posedge clk_ref)
   cp_name_0: coverpoint  clk_adc_en    ;
   cp_name_1: coverpoint  clk_dac_en    ;
   ......
endgroup

这里随便举例两个时钟的门控使能,实际上 我们需要将所有待验证的时钟门控信号定义成功能点,当测试激励中驱动了这些控制信号,则可以通过覆盖率报告查看,以便验证人员能够及时查漏补缺。

再次举例:假设我们对以下几个时钟分频控制字进行功能覆盖率建模:

covergroup clk_div_cfg @(posedge clk_ref);
   cp_name_0:  coverpoint adc_div_num {bins bin_name[] = {[0:3]};}
   cp_name_1:  coverpoint dac_div_num {bins bin_name[] = {[0:2]};}
   cp_name_2:  coverpoint clk_src_sel {
                                       bins bin_name_1 = (1=>2) ;
                                       bins bin_name_2 = (1=>4) ;
                                      }
   ......
endgroup

上面这个功能组内主要定义各个模块的时钟分频情况,比如cp_name_0,我们需要检查adc_div_num是否在测试激励中cover了0~3的情况,cp_name_1,我们需要检查dac_div_num是否在测试激励中cover了0~2的情况,而cp_name_2,我们需要检查测试激励是否出现过值从1跳转到2,以及从1跳转到4的情况。

当然,这里只是简单举例,具体定义还要根据实际需求去分配功能点的定义。

最后,我们对定义的功能覆盖组进行初始化。

clk_en_cfg  u_clk_en_cfg_obj;
clk_div_cfg u_clk_div_cfg_obj;

initial
begin
  #1;
  clk_en_cfg_obj  = new();
  clk_div_cfg_obj = new();
  #1e3;
  clk_en_cfg_obj.stop();
  clk_div_cfg_obj.stop();
  #1e3;
  clk_en_cfg_obj.start();
  clk_div_cfg_obj.start();
end


总结

       利用工具自动统计功能覆盖率,包括上述我们自定义的功能group,以及上述几个章节中自定义的断言都可以进行统计,通过覆盖率情况,可以很好的查看我们的自动化checker是否都被执行过,一旦所有的checker都被执行过,且都没有上报错误,说明我们的验证checker以及RTL代码都有一定的鲁棒性。同时可以分析覆盖率报告,根据报告情况指导验证人员及时补充相应的测试激励,使验证快速收敛。

你可能感兴趣的:(fpga开发,单片机,嵌入式硬件,开发语言,前端,青少年编程,汇编)