关于时钟模块完备性验证方法第一章

系列文章目录


第一章  时钟门控检查


文章目录

  • 前言

    一、什么是时钟门控?

    二、SystemVerilog assertion

    1.利用断言的方式来进行门控的检查

    2. 对上述断言进行解析

    总结


前言

随着集成电路的规模越来越大,系统中所需要的时钟系统也越来越复杂,如何保证时钟验证的完备性一直是众多验证工程师追求的目标,本文就系统中时钟模块的验证完备性进行探讨,包括时钟门控、时钟频率、时钟占空比、时钟glitch、时钟相位、以及参考模型等。

为了更好的保证系统时钟验证的完备性,有时候需要同时使用多种技术手段进行全满cover,而这里介绍的多种方法结合并非仅仅是指数量上的增加,而是需要首先清楚整个时钟结构,针对基本的时钟电路选择对应的方法即可,但是针对潜在的风险点,则需要灵活运用以上方法的结合,甚至自定义新的方法都是有可能的。本人在开发这些方法的时候,大多数技术方法也是根据实际验证需求,寻找到了某种对应的方法去cover它,不一定是最优的,但一定是实用的。

要想熟练掌握时钟模块验证的各种方法,我们还得从基本的、简单的技术方法讲起。

本章节我们首先来了解一下时钟门控的验证方法,关于其他方面的验证方法请查阅本系列文章其他章节部分。


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

一、什么是时钟门控?

所谓时钟门控,是为了低功耗设计而诞生的,在实际工作中,有很多低功耗设计方法、其中时钟门控就是一种常用的技术方法、另外还有像UPS等也可以实现低功耗管理。那什么是时钟门控呢?打个比方,我们在clk_gen产生了某个时钟,接到了其他模块的某个DFF的CK端,那从时序上来看,DFF的CK端口就是一串连续的时钟toggle,但是,在实际电路中,当这个DFF端设计为带门控的逻辑时,我们只会看到当门控有效时,DFF的CK才有效,其他时候CK都是无效的低电平。这就是门控的意义,只在DFF有数据需要翻转的时候才会把时钟放进来,其他时候都会被gate住,因为在实际电路中,很多时候DFF并不是需要时时刻刻都有数据翻转的,因为为了降低没必要的时钟翻转,即为了节省功耗,就诞生了时钟门控的概念。

还有一种方法,为了更大程度的降低功耗,即避免时钟树上的功耗,更多时候我们会直接在时钟源头做门控处理,通常情况下使用一个软件可控的寄存器做为时钟的enable/disable,当enable有效时,clk_gen会把时钟通过时钟树传递给目标DFF的CK,当disable时,clk_gen直接将时钟关闭,包括时钟树上都将不会见到clk翻转。

当然,以上介绍的内容可能设计到数字设计方法的内容,包括低功耗设计的原理和方法,我们今天要介绍的内容,是如何去验证时钟门控的问题。当一个时钟方案设计中有门控信息时,我们验证要去验证spec中指定的时钟与时钟门控是否完全一致。

二、SystemVerilog assertion

1.利用断言的方式来进行门控的检查

代码如下(示例):

property inst0
@(posedge ref_clk) disable (!clk_en_check) $rose(clk_a_en) |-> ##[0:10]
$rose(clk_target);
endproperty
a_check_clk_en_0: assert property(inst0)
      else begin
         $display("==== a check have err at %0t", $time);
         err_num++;
      end

property inst1
@(posedge ref_clk) disable (!clk_gen_check) $fell(clk_a_en) |->
##10 ($stable(clk_target));
endproperty

a_check_clk_en_0: assert property(inst0)
  else begin
  $display("==== a check have err at %0t", $time);
  err_num++;
  end

2. 对上述断言进行解析

property inst0
@(posedge ref_clk) disable (!clk_en_check) $rose(clk_a_en) |-> ##[0:10]
$rose(clk_target);
endproperty

其中ref_clk为我们验证自定义的一个高频参考时钟,我们利用该时钟去采样clk_target,要求ref_clk的频率一定要高于clk_target,否则可能采样不到clk_target,导致该断言无法成功。

clk_en_check为我们验证环境中定义的一个临时变量,可用于控制是否打开此断言。这个可以根据需求随时控制是否打开此断言。

当我们打开了断言使能,一旦clk_ref采样到了门控使能信号clk_a_en有效,即激活断言,那么从当前时刻开始,要求在10个ref_clk周期内,必须采样到clk_target为高电平。这里我们假设clk_target默认值为低电平,即一旦断言成功,说明一旦使能门控信号打开,即可以检测到时钟翻转,即时钟被成功打开了。

a_check_clk_en_0: assert property(inst0)
      else begin
         $display("==== a check have err at %0t", $time);
         err_num++;
      end

这里是为了统计覆盖率用的,因为一旦我们对系统中大量的时钟门控进行建模,我们需要一个指标来论证是否所有的时钟门控全部被cover到,因此通过统计覆盖率来直观的检验验证checker的质量。另外,一旦断言失败,我们可以通过向验证环境中返回一个err_num,来告知更上层的应用最底层某个地方发生了异常。

property inst1
@(posedge ref_clk) disable (!clk_gen_check) $fell(clk_a_en) |->
##10 ($stable(clk_target));
endproperty

a_check_clk_en_0: assert property(inst0)
  else begin
  $display("==== a check have err at %0t", $time);
  err_num++;
  end

增加这个是为了更进一步验证该时钟门控的有效性,这句话的意思是,当clk_a_en无效,即门控被关闭时,等待10个ref_clk周期,clk_target必须保持稳定,这里可以稳定到高电平、也可以稳定到低电平,取决于设计。但是一定不能继续翻转,否则就可以认为该门控无法正常关闭时钟。


总结

例如:以上就是今天要讲的内容,本文仅介绍了时钟门控的验证方法,该方法不一定是最优的,但是经过项目实战过,具有一定的参考性,在实际工程中,可以根据需求对齐进行扩展,灵活运用。

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