听说SPI访问寄存器的功能覆盖率很难?UVM助力实现方案来啦!

 

摘要

虽然UVM寄存器抽象层支持功能覆盖率的收集,但是,对于复杂的寄存器访问场景,现有的元素显得并不充分。利用串行外设接口(SPI)访问寄存器带来了一种全新的挑战,这是由于比特分辨率访问级别和低级别通信参数已成为功能覆盖率的必要部分。外部功能覆盖率订阅器加速了这些单元的处理,与此同时也提供了将影响寄存器访问的其他因素(例如,功耗管理)纳入覆盖率度量指标的选项。

 

一、引言

寄存器空间的验证是验证过程中的关键任务之一。寄存器实现当中的任何bug将意味着一个错误的设备操作。如果SPI被用来访问寄存器,验证的复杂度将随之提高。主要的挑战来源于,为了支持逐比特访问,必须打破UVM手册中仅仅支持的字节访问。其他参数,例如低级别通信时序,也需要考虑。因此,通过串行总线访问寄存器的功能覆盖率包含了一种并不适用于并行接口的非常特殊的元素集

在之前的实践中,做过一些修改的UVM寄存器抽象层(UVM_REG)非常适合于该器件寄存器空间的建模。然而,即使作者原本计划使用UVM_REG内建的覆盖率收集组件,结果证明它们有某些不能直接克服的限制。此外,寄存器模型本将可以意识到一些低层级的协议属性,从而打破它的模块化。

更为合适的是使用一个单独的覆盖率收集组件。该组件作为一个订阅者专门观测SPI通信,同时也会引用寄存器模型和其他感兴趣的组件,例如功耗监视器

 

二、验证环境

 

A、SPI监视器

根据UVM,接口监视器扮演一个被动观测总线接口信号的角色。它从总线提取信息,并且创建一个可被环境其他部分处理的事务。

典型的监视器是一个继承于uvm_monitor的类,它是UVM库中的一部分,包含一个虚接口,总线信息可以通过它而被访问。数据收集在预定义的run_phase任务中被执行,收集到的事物通过一个TLM analysis端口被传输,如图1所示。

监视器也可以在低层次的协议层执行数据比较和基本的覆盖率收集,也可以被用来处理协议特定的需求,例如频率测量。

       

图1 SPI监视器

 

 

B、层次监视器

为了克服UVM_REG在部分寄存器访问方面的限制,在接口监视器寄存器模型预测器之间放置了一个中间组件。虽然UVM手册并不支持通过uvm_adapter类supports_byte_enable域访问部分寄存器,但仍然建议保留byte级的颗粒度。为了处理bit级访问,层次监视器订阅SPI监视器的analysis端口,并且引用寄存器模型。预测机制如图2所示。计算出来的值被提供给预测器以便做进一步处理。不论寄存器的大小,该解决方案都适用,并且可以被扩展以支持其他需求,如bit级或byte级提取。

       

图2 层次监视器中的部分访问预测机制

     

 

 

 

C、预测器

预测器组件的主要功能就是执行寄存器模型的更新。一旦预测器通过预定义的bus_in analysis export得到一个观测到的事务,就会触发相关adapter的bus2reg方法。该方法会将该事务转化为一种适合的通用格式。如果读比较使能打开,就会将读到的值与正在访问寄存器的镜像值进行比较。预定义的sample方法在寄存器和寄存器块级被调用。最终,新的镜像值被预测,同时累加定义的寄存器访问方式计数器。

 

三、UVM_REG覆盖率API

 

D、概述

由于寄存器覆盖率模型跟寄存器和域的实现完全独立,UVM不提供任何隐式覆盖。然而,为了决定某种覆盖率组例化与否,它确实提出了利用标识符指定功能覆盖率的类型

表1中列出了一些预定义的标识符。可以添加用户或厂家定义的标识符,以处理UVM手册本身不支持的覆盖率模型。

 

表1 功能覆盖率标识符           

为了包含覆盖率模型,测试用例编写者或许应使用uvm_reg类的静态方法include_coverage。由于标记值使用独热编码,多种覆盖率模型可以被包含进来。此外,指定命令用到的寄存器或寄存器块的绝对路径也可以作为参数提供给该方法。图3展示了多种选项。

       

图3 包含覆盖率模型

      

 

 

寄存器模型开发者利用build_coverage作为参数将所有支持的覆盖率模型罗列在寄存器或寄存器块的构造函数new()当中。最终,has_coverage方法检查某种覆盖率模型是否被支持和包含,在该种情形下,相应的覆盖率组被例化。

在寄存器级,UVM寄存器手册提出了两种覆盖率组,致力于域值覆盖和表示读/写类型的数据比特的寄存器访问覆盖。图4展示了它们的例化。图5展示了覆盖项实现的定义。

       

图4 寄存器级覆盖率组的例化

      

                                                                                     

 

       

图5 寄存器级覆盖率组的定义

      

                                                                                     

 

在寄存器块级,UVM手册也提出利用两种覆盖率组,致力于域值覆盖和表示访问地址的寄存器访问覆盖。前者跟寄存器级的实现类似,但是寄存器块级加强了不同寄存器中域值的交叉覆盖。图6展示了它们的例化。图7展示了覆盖项实现的定义。

 

       

图6 寄存器块级覆盖率组的例化

      

                                                                               

 

       

图7 寄存器块级覆盖率组的定义

      

                                                                               

 

默认情况下,在寄存器模型中,所有覆盖率组的采样是关闭的。要使能某种覆盖率模型的采样,应该使用set_coverage方法,如图8所示。如果在寄存器块中被触发,该方法在所有子组件中将被递归调用。

            

图8 覆盖率采样使能

                                                                                     

 

寄存器和寄存器块级提供了两种预定义的虚方法来执行覆盖率组的采样。在预测之前,方法sample被预测器自动触发。方法sample_values应该从环境中被显式调用。在这两种方法中,使用get_coverage方法(该方法用来检查某种模型是否被包含和支持、以及该模型的采样是否被使能)来对已实现的覆盖率组进行采样。图9和图10分别展示了两种方法在寄存器和寄存器块级的实现。

 

       

图9 寄存器级覆盖率的采样

      

                                                                                   

 

       

图10 寄存器块级覆盖率的采样

      

                                                                               

 

图11总结了利用UVM_REG API实现功能覆盖率收集过程中的所有步骤。

  1. SPI事务被SPI监视器收集;

  2. 收集到的事务通过一个TLM analysis端口被发布;

  3. 部分访问由层监视器处理;

  4. 适配器的bus2reg方法被触发;

  5. 事务以合适的通用格式被提供给预测器;

  6. 读值检查;

  7. 寄存器级和寄存器块级覆盖率组采样;

  8. 预测。

       

图11 UVM_REG覆盖率收集

                                                                               

 

按照该向导,一些简单项目的覆盖率,例如事务方向、数据地址或当前寄存器的状态,可以很好地处理。然而,与使用UVM_REG工程师工作的经验表明这些特征非常容易出错。一些典型的错误包括:

  1. 在写和读数据的地方使用uvm_reg_field类的值;

  2. 在镜像值的地方使用uvm_reg_field类的值;

  3. 不能理解预测器操作的顺序--采样发生在预测之前;

  4. 不能理解API方法的含义--include_coverage、build_coverage、has_coverage、set_coverage、get_coverage的角色容易混淆;

  5. 忘记使能覆盖率采样;

  6. 不能完全依照向导来做--例如,无条件地采样;

  7. 不能理解sample和sample_values方法的应用模型--sample_values不会被自动调用;

  8. 在寄存器中引用环境的其余部分--影响复用性

另一个缺点在寄存器类中定义的覆盖率组降低了代码可读性。最后,涉及任何包含连续访问多种寄存器的场景,其余的事务域或非寄存器内容的情况都会在寄存器模型和测试平台其余部分之间产生所不期望的依赖性。

基于以上这些限制,利用外部覆盖率收集订阅器是一种更加便捷的解决方案

 

四、外部功能覆盖率订阅器

 

E、基本覆盖率

除了UVM cookbook中提到的好处,外部组件的开发在串行总线接口访问寄存器的情况下非常有优势,其结构如图12所示。在这种情形下,除了最基本的寄存器访问域值覆盖率该寄存器模型可以包含许多关键的寄存器访问相关的item。为了支持在需要的时候创建覆盖率组,所有实现的覆盖率组被封装在uvm_object当中,如图13所示,展示的是覆盖率组支持域值覆盖率。图14展示的覆盖率组通过收集访问地址和事务数据执行寄存器访问覆盖率。其中也包含当前寄存器内容的信息。这对于只读状态寄存器是必要的。对于它来说写访问应当被忽略,无论其值为多少。

       

图12 外部覆盖率订阅器结构

  

                                                                             

       

图13 一个封装在覆盖率组容器中的覆盖率组

                                                                   

 

 图14 寄存器访问覆盖率

    

                                                                             

 

F、部分访问覆盖率

通过SPI接口访问寄存器,比特级访问是一定要支持的。因此,部分和溢出场景成为覆盖率模型的一个关键组件。外部订阅器提供了一种将事务长度包含于覆盖率指标的简单方法,如图15所示。

 

图15 部分访问覆盖率

  

                                                                           

 

 

G、低级别通信覆盖率

只要不违反协议,低级别的SPI通信时序不应该影响寄存器访问,我们也实现了专用时序相关的覆盖item。图16展示了SPI时钟频率覆盖率,器件在该频率下访问寄存器。SPI监视器执行频率测量。

 

 图16 SPI访问时钟频率覆盖率

   

                                                                     

 

 

H、功耗管理

为了降低功耗,芯片或许使用了多个功耗域。全局功耗监视器观测输入信号,例如电压和复位引脚,并且决定某个寄存器是否打开。我们利用锁定域回调技术在关闭的功耗域内禁止访问寄存器。图17展示了回调的实现。验证侧需要覆盖的一个关键场景是功耗被关闭时,该时寄存器变成只读。读尝试导致读取值隔离。图18展示了定制的覆盖率组。

       

图17 功耗供给模型回调

      

                                                                                 

       

图18 功耗供给覆盖率

 

                                                                               

 

 

I、寄存器交叉

多个寄存器之间交叉场景的覆盖率是功能覆盖率的一个重要方面。例如,为了处理中断逻辑,一组寄存器用来使能、清零或指示中断状态标志。尤其感兴趣的是正确实现优先级处理逻辑,当访问中断清零寄存器的时候,需要触发一个中断。通过使用过度仓可以获得需要的指标,如图19所示。如果采样到连续地访问地址`REG1_O和`REG2_O,第一个覆盖点中的仓将被覆盖到。第二个覆盖点包含仓表达式:(READ,WRITE=>READ,WRITE)

它可以扩展成4个过渡仓:(READ=>READ)(READ=>WRITE)(WRITE=>READ)(WRITE=>WRITE)

由于使用了仓数值结构TRAN_RW[ ],创建的4个过渡仓之间彼此关联。最后实现了两个条件之间的交叉覆盖率。

 

图19 过渡覆盖率

   

                                                                                 

 

图20总结了利用外部组件实现功能覆盖率收集过程中的所有步骤。封装的覆盖率组在组件中例化而不是在寄存器模型中。步骤(9)代表它们的采样。

       

图20 利用外部组件的覆盖率收集

                                                                     

 

 

五、总结

利用上述解决方案,寄存器模型和寄存器的功能覆盖率实现了分离。UVM寄存器抽象层的主要优势得到保留,例如通过寄存器序列产生抽象的、可重用的激励和内建的比对机制。然而,除了依靠内建的UVM_REG元素引用寄存器模型的外部组件被用于实现覆盖率收集。这加速了一些复杂场景的覆盖率收集,例如,寄存器交叉和功耗管理影响。而且,当低级别通信元素正在执行覆盖率收集的时候,寄存器模型也不会受到低级别通信细节的影响。

 

原文来自:DVCon2017_USA, 点击阅读原文去路科官网下载DVCon2017论文合集,还有更多资料等你来哦!

扫描上图二维码可直达课程页面,马上试听

往期精彩:

获取验证通关密语,就在本周日开班的验证V2课程

30w+还送股送房?60+IC企业2019薪资全面攀升!

UVM RAL模型:用法和应用

我们准备做第二期线下培训,依旧认真且严肃

如果你突然被裁员了,你的Plan B是什么?

[彩虹糖带你入门UVM]

理解UVM-1.2到IEEE1800.2的变化,掌握这3点就够

  • 1
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值