我要投搞

标签云

收藏小站

爱尚经典语录、名言、句子、散文、日志、唯美图片

当前位置:大丰收高手论坛 > 动态仿真 >

验证的方法篇之一:动态仿真

归档日期:08-06       文本归类:动态仿真      文章编辑:爱尚语录

  》,之所以单独分出一季来介绍验证的方法和工具,一方面是目前验证方法的分支和其工具种类繁多,另外的是希望读者可以在系统了解了验证的工具库之后,在验证设计的时候首先有一套工具箱,而后再根据设计的特点将其结合不同的验证方法和工作,最终取得满意的效果。

  从Wilson 2014年调查数据来看,验证占据了主要的人力资源,同时也是设计能否达标低缺陷率的主要保障。从2007年到2014年的增长趋势来看,由于设计的复杂度逐年攀升,与之带来的验证压力和实际人力资源配置都相应提高。除了人力的投入,设计自动化(DA,design automation)工具关于验证的方法、特性、性能提高都在协助验证人员来面对新的验证挑战。

  到了目前的阶段,已经没有一种单一的工具、语言或者方法可以提供用来实现验证完备性。实际的验证工作中,我们需要通过多种语言、方法、脚本、工具最终达到验证的的目的。这些不同的语言、方法、脚本和工具之间没有绝对的优劣,比如仿真验证方式会协同形式验证方式一同来完善功能覆盖率,也有可能通过不同语言的脚本之间的整合来最终完成一项验证流程。总而言之,作为一名有经验的工程师,他需要在掌握现有的各种方法和工具的前提下,通过合理的选择,最后“保质高效低耗”地完成验证任务。

  所以,我们将根据验证的方法分为若干类为大家梳理目前主流的验证方法和工具。这些主要的验证方法可以分为:

  在此之上,我们额外引入一篇开发环境来将日常的编码环境与大家介绍,所谓工欲善其事,必先利其器,有一个应手的开发方式,也是迈向高效率的一步。

  这一篇我们为大家带来日常最常见的验证方式动态仿真(dynamic simulation),该方式其实就是通过测试序列和激励生成器给入待验设计适当激励,结合时间的消耗,进而判断输出是否符合预期的。简而言之,我们需要仿真器来配合这一项工作,验证人员也需要通过查看比较结果、仿真波形比对最终来判定测试用例是否通过。如果按照激励生成方式和检查方式的不同,我们又可以将动态仿真中的验证方式分为:

  由于参考模型一般都会伴随着直接测试或者随机测试,所以我们接下来带着大家着重了解这三部分:直接测试、随机测试和断言检查。

  直接测试指的是激励的值在仿真之前已经决定下来,测试用例给出的激励序列会在下一次重新提交任务以后保持不变。我们日常会通过C/C++/汇编代码来实施测试用例,该场景最常见的是SoC子系统级或芯片系统级的测试,因为待验设计一般会包含处理器在期中,而且根据硅后测试复用的角度,我们也倾向于运用C代码来编写测试用例。

  从下图中可以看出,测试用例经过编译、二次映射成为硬件存储器可以读入的镜像文件(一般为二进制文件,主要包含地址和数据两部分)。待验设计经过上电复位(power up and reset)以后会从存储器中读取二进制文件,进而处理器会将二进制数据译码(decoding)为指令和数据进行运算或者寄存器访问。而最终的数据比较分为两种情况:

  有时候我们也会考虑直接将第三方提供的可执行文件或者预先映射的二进制文件作为激励源交给存储器,这就跳过了C代码编译的步骤,也需要额外的运行环境兼容措施。

  我们将上述的直接测试的流程对照到实际项目中,如下面这个例子,测试用例可以通过C代码交给处理器,进行硬件行为的仿真检查。如果在模块验证环境中缺少处理器,我们如何在这一级实现C代码的垂直复用(从模块级到芯片系统级)呢?可以考虑下面的步骤:

  上面的步骤中需要引入转换器实现复用,我们也可以考虑将转换器和总线翻译器结合成为SystemVerilogC-DPI的形式来将翻译层通过标准的C-DPI接口实现更多的复用性。关于SystemVerilog C-DPI的实践方式我们会在后面的篇章《SystemVerilog实战点全讲》里跟大家详细讨论。

  直接测试的运用场景一般会在模块测试的早期或者在系统级芯片测试场景中,它适合于测试待验设计的基本功能,且能最直接地翻译出验证人员想要的场景,而它的缺陷也较明显那就是,每一个直接测试用例在通过之后的重复仿真是冗余的,因为这不会提高更多的覆盖率,也无法产生新的测试序列。不过也正因为它的激励序列确定性(determinacy),直接测试有时候可以构成基本测试表来在验证前期保证设计的基本功能。

  与确定性序列相反的则是随机序列(random sequence),随机序列通过预先定义的约束每次随机产生合理的数值,进而通过激励产生器给出测试序列。下图可以说明,与直接测试相比,随机测试用例可以直接通过激励生成器转化为测试序列。

  产生随机数的方法有很多种,有很多语言可以实现,但是考虑到灵活地给随机绑定一些约束的时候,我们需要特定的语言提供这样的属性,目前常用的语言有SystemVerilog和e语言。从下面Wilson 2014年调查数据来看,SystemVerilog的 使用率大致已经上升到了75%以上。

  约束实际上是随机激励能否符合接口协议,以及朝着验证焦点而去的关键。随机约束生成器一般可以通过静态约束或者动态反馈约束来给出每一轮的激励。从下图可以看出,在实际的验证环境中,往往有很多对随机约束起到控制和反馈的因素,它们分别是:

  静态随机约束:即默认的约束,一般是同激励一起定义的,不会随着测试而变化。

  反馈的动态随机约束:在测试的过程中通过上一轮的结果来对下一轮随机序列给予反馈,通过额外的定向约束(biasing constraint)给出更小的随机域(random region)。

  待验设计的功能验证开关:待验设计的功能点有时候可以通过测试序列来关联,进而从该序列是否要验证某一项功能来决定某一组随机约束是否生效。

  激励的结构成员:随机激励的成员构成,一般分为接口成员(跟设计交互),和成员间的逻辑变量(决定成员之间数值关系的变量)。

  验证环境的配置参数:验证环境如果是可以配置的,那么这些配置参数也可能会影响序列的产生。

  验证环境中不同激励组件之间的同步通信:如果验证环境中包含多个激励组件,那么如果要实现这些随机组件之间的协同,我们就需要考虑它们之间实现同步通信(synchronization communication)来实现激励组合之间的合理性。

  目前常使用的一种随机验证方式是基于覆盖率驱动的,而这种方式也同我们上面提到的影响随机生成的因素“反馈的动态随机约束”一样。从下图可以看出,与常用的随机约束验证方式不同的一点是,覆盖率收集器在每次测试中都会通过监视器来收集覆盖率(主要指功能覆盖率),将其与已有的覆盖率数据库进行合并,同时根据现有的覆盖率数据库来为下一次随机约束给出反馈。这些正向的反馈就是用来进一步缩窄随机约束域,使其能够定向产生一些序列来覆盖那些未知的功能测试点。

  对于测试用例而言,它可以指定每一次激励的数据内容,也可以在较高层次上指定每一次激励数据包(data packet)的内容。我们在之前《设计的流程》中就介绍过用TLM建模来在产品定义早期对设计建立模型,而TLM本身是就模型层次而言,它在更高一级用来描述设计或者验证环境。对于基于TLM的随机验证方式,它指的是在随机环境中使用到的最小颗粒是TLM级别的数据包。该激励数据包中不只是包含一个时钟周期内该给出的激励,而是在更长的时间范围(一般为一次完整的数据操作,例如完整的数据读写或者完整的数据包传输)将使用到的数据都加以定义。

  通过TLM级别的验证方式带来的好处是验证人员可以更为便捷地描述一些测试场景,更加贴近于真实的用例。这也是因为真实的用例,例如硅后系统测试和固件开发时基于系统级别的高层次,它们专注的并非某个模块的某一项功能,而是关注于某个子系统或者整个系统的联合工作模式。

  从下面这张图可以看到,TLM测试用例由于抽象级较高,需要有TLM2RTL激励生成器来做进一步的转换。我们将TLM激励生成器进一步放大以后可以看到它内部的一些转换模块,包括读写操作、复位操作、中断操作还有其它操作。这些方法一般都是根据TLM操作命令经过翻译来使用的,我们将这样的激励生成器称之为总线功能模型(BFM,bus functional model),它的作用就是将高抽象级的TLM命令转换为低抽象级的硬件端口时序。进一步看,在高抽象级到低抽象级的转换中,除过数据抽象度是在降低以外,激励所用的时间也在转换中被实现加注到待测设计接口上面了,因此要完成一项TLM命令的转换,经常需要数十上百个时钟周期。

  影响验证产出的一个重要因素是如何将功能描述部分准确地描述,因为准确地描述可以帮助验证人员更方便地去翻译功能描述文档。而对于设计人员而言,他们也需要去捕捉各种可能设计行为来证明设计符合预期。断言(assertion)就提供了这样的特性,它善于针对某一个特定的逻辑或者时序进行预设,一旦设计的实际行不符合断言的描述,则会给出检查报告。

  断言本身不限定于某一种语言或者工具,而是就它的特性来讲,它可以准确地描述出设计的预期行为。所以有多种实现断言的方法和工具,在近来的20年间,这些被业界支持的基于断言的验证方法和工具如下图所示,在这里我们按照断言方法不同的运用过程可以将它们分为如下几类:

  广义的验证模块,不依赖于特定的语言或者工具,例如OVL(Open Verification Language/Accellera),这些验证库中含有多个常用的验证模块,可以用来在设计中例化。

  由于断言的使用可以分为在验证平台中和插入到设计中,这也使得断言可以同时为验证人员和设计人员所使用。使用断言的优势在于以下几个方面:

  由于断言的位置更贴近于不同功能点的源码位置,这使得一旦相应检查的功能点发生错误,可以更快更清晰地定位出错误源。

  断言自身可以表达更长的时序,覆盖任意长度的功能时序,这就使得它可以在更高的抽象级别来描述设计行为。

  由于断言可以被直接置入到设计中(无论是设计人员置入还是验证人员置入),这都使得断言可以在不同的层次上得到复用,这使得它有更久的生命周期和验证延展。

  这里谈到了断言的复用性,实际上断言的应用场景非常多,且它自身便捷的即插即用的特性使得有多种可选的商业断言IP。下面这个例子用来说明断言运用的场景以及它可以垂直复用的特性。

  集成连接:例如片上网络多个发起端和目标端之间的访问路径检查,或者系统集成中各个模块之间的连接关系。

  总线协议:针对工业标准总线,有商业验证IP可以协助准确验证设计是否按照总线协议实施。

  数据一致性:对于存储单元,数据的一致性检查可以通过检查端口读写来预期数据的一致性。

  输入限定:基于假设的输入限定也可以通过输入端的断言来判断输入首先是否符合预期,这对于错误源排查也有帮助。

  自定义断言:用来检查各个设计的细节,通常这些细节属于设计人员和验证人员关注的功能焦点。

  从复用角度来看,断言可以实现从模块级到子系统级再到芯片系统级的垂直复用。从上图可以看出,从单元1在模块级验证时插入的断言“数据进出”和“状态机”两部分在子系统级和芯片系统级两个环境都可以保持监测检查的状态,这一点要归功于断言可以作为非综合模块被置入到设计中,或者通过绑定的形式作为模块并行于设计进行例化(同时不影响设计结构)。而在子系统中,新的断言部分“子系统集成”又可以实施用来检查从单元1与从单元2之间的集成关系,这一关系检查在芯片系统中也可以继续保留下来。

  至此,我们将动态仿真验证的方法介绍完了,在今后更多的篇章中还将对这些主流方法进一步讨论。下一篇将会同大家一起领略《静态检查》的魅力。

本文链接:http://quangdungfc.net/dongtaifangzhen/659.html