《编写测试平台-HDL模型的功能验证.pdf》由会员分享,可在线阅读,更多相关《编写测试平台-HDL模型的功能验证.pdf(85页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、第1章 什么是验证验证不是一个测试平台,也不是一系列测试平台的集合。验证是一个证明设计思路如何实现的过程。验证贯穿于我们的日常生活中:支票簿的结算、品尝食物、在地图上寻找用标记标出的特定目标,这些都是验证的过程。本章将从重要性和代价的角度介绍验证的基本概念,以及如何确认验证的内容。我们将讨论不同的验证方法之间的差异、测试和验证之间的差异。也将介绍验证在设计复用中的重要性,以及验证复用时所面临的挑战。1.1 什么是测试平台术语“测试平台”(Testbench)通常指一段仿真代码,用来为设计产生特定的输入序列,也用来观测设计输出的响应。测试平台常常采用VHDL、Verilog、e或OpenVera
2、语言编写,有时也会调用一些外部的数据文件或C 函数。图1.1是一个测试平台和待测设计(DUV)之间相互关系的示意图。测试平台为设计提供输入信号,并监视设计的输出信号。注意,这个系统是一个完全封闭的系统:系统没有来自外部的输入信号,也没有输出信号。测试平台是系统的控制核心。验证的任务就是确定产生什么样的输入模式,以及期望的设计输出。图1.1 一种常见的测试平台和待测设计的结构1.2 验证的重要性大多数书籍关注语法、语义和语言的RTL 子集典型的VHDL和Verilog书籍的大多数章节都在介绍语言的语法和语义,通常也会用两三章的篇幅介绍可综合性编码风格或寄存器传输级(RTL)语言子集。待测设计测试
3、平台编写测试平台HDL 模型的功能验证(第二版)2这些书籍通常只用一章的内容来介绍测试平台。但是一章的内容不足以解释清楚与测试平台有关的知识,并且这些解释常常是非常简单的。几乎所有的书籍都把测试平台用到的技术局限于产生同步方式的激励矢量,用波形浏览工具检测输出信号。大多数书籍介绍语言的文件输入功能,把更多的内容安排在语法和语义方面。这些书籍中大部分的内容是在讲述如何编写可综合的VHDL或Verilog代码,而不是强调如何编写验证功能正确性的测试平台,因此读者会得出前者比后者更重要的结论。事实上,这与所有的硬件设计队伍的结论相悖。验证工作占设计工作量的70 在这个设计规模达数百万门ASIC、可复
4、用的知识产权(IP)和系统芯片(SoC)的时代,验证占到了设计工作量的70。设计团队应该配备能够正确描述验证需求的工程师和专门进行验证的工程师。验证工程师的数量甚至应该是RTL 设计人员的两倍。验证是必不可少的由于验证的工作量巨大,以及缺乏合格的硬件设计和验证工程师,因此几乎所有项目的验证都不能及时完成就不足为奇了。事实上,我们经常在设计完成后才考虑验证工作。当设计进度受到影响时,问题就会产生。这也是现在的新工具和方法学把验证作为研究目标的原因,它们试图通过并行化、更高层次的抽象和自动化来缩短验证需要的时间。并行化可以缩短验证所需的时间如果验证工作可以并行进行,那么就可以使用更多的资源来缩短验
5、证所需的时间。这就好比在地上挖一个坑,可以让很多拿着铁锹的工人一起来挖。为了让验证工作得以并行进行,必须让编写代码、调试、验证以及设计的实现过程都并行化。抽象可以缩短验证所需的时间采用更高层次的抽象使我们可以不关心底层的细节,从而提高工作效率,这就好像在上面的例子里使用挖土机来挖坑。抽象减少了对底层细节的控制高层次的抽象通常伴随着对底层控制的减少,因此必须仔细选择。高层次的抽象要求额外的训练以理解抽象的机制及其后果。使用挖土机挖坑会遇到同样的失去控制的问题:工人不再直接和泥土打交道,而是操作操作杆和踏板。挖掘的工作更快,但精度降低了,并且只有受过训练的工人才能工作。验证工作可以在更高的抽象层次
6、完成,例如事务级、总线周期级甚至更高的层次,而不是在底层直接和0、1 打交道。第1 章 什么是验证3自动化可以缩短验证所需的时间自动化可以让我们在机器自主地、快速地完成任务的同时做别的事情,得到可预测的结果。自动化需要编写定义好输入和输出的标准进程。并不是所有的过程都可以自动化,这就好像使用通用的机械不可能挖各种不同形状、尺寸、深度、位置和土质的坑一样。验证面临着同样的问题。由于要验证各种不同的功能、接口、协议和变换,现在的技术无法采用一种通用的自动化解决方案来进行验证,而只能将某些验证过程自动化,特别是在一些专业的应用领域。这就好像挖沟机可以自动挖出放置管道和电缆的浅沟。用来自动化各种验证过
7、程的工具正在不断出现,例如,有些工具可以从高层次抽象的规范自动产生总线功能模型。随机化可以作为一种自动化工具在一些特殊领域,随机化可以用来模拟自动化。通过构造一个随机发生器来产生在特定范围内的有效输入,就有可能自动产生所有感兴趣的输入状态。例如,打扫一个池塘底部的过程可以由以下自动化过程实现:用一个扫帚在池底部自动地随机移动,池的四壁对移动的范围加以限制。几个小时后,可能只剩下角落和几小块地方需要手工清扫了。要取得同样的结果,这种自动化的过程需要更多的计算时间,但它是完全自动的,因此可以让重要的资源去实现其他关键的任务。这个过程可以通过同时运行数个随机发生器并行进行。它们可以通宵运行,从而增加
8、了总的生产时间。1.3 恢复模型恢复模型(reconvergence model)是验证过程的一种概念表述,人们使用它来精确地解释验证的对象是什么。你知道到底在验证什么吗必须回答的最重要的问题是:你正在验证什么?验证的目的是保证某种变换的结果和预期的结果一致。例如,对支票簿结算的目的是确认所有的交易都被准确地记录下来,并且所记录的结余反映了总的可用资金。验证是通过各种方法核对设计规范和输出结果一致性的过程图1.2表明了一种变换的验证只能通过另一条有公共起点的恢复路径完成。这里提到的变换可以是任何具有输入和输出的过程。设计规范的RTL编码、插入扫描链、将RTL代码综合成门级网单,以及门级网单的版
9、图设计都是硬件设计中的变换。验证是检查变换的结果和变换的起点是否一致的过程。如果变换和验证没有共同的起点,那么就不存在验证。优化这些并行进行的过程以减少重复次数是另一个问题。编写测试平台HDL 模型的功能验证(第二版)4图1.2 验证中的恢复路径可以用图1.3所示的支票簿例子来解释恢复模型。变换和验证的公共起点是支票簿中记录的上个月的结余。变换的过程就是在一个月的周期内开出支票、收取支票和还款。验证就是检查支票簿上最后记录的结余是否和本月银行的对账单一致。图1.3 结算支票簿是一个验证的过程1.4 人为因素如果端到端的变换过程不是自动完成的,那么就必须由人(或小组)对设计规范加以解释,然后完成
10、变换。RTL编码就是一个这样的例子。设计小组对书面的设计规范加以解释,并完成他们认为功能正确的、可综合的HDL代码。通常每位工程师都要自己验证这些代码是真正“功能正确的”。根据自己的理解而不是设计规范去验证设计文件图1.4展示了上述情况的恢复路径模型。如果由同一个人对设计规范加以解释,编写RTL代码,并完成RTL代码的验证,那么验证和变换的共同起点将是“所做的解释”,而不是设计规范。图1.4 不确定状态下的恢复路径在这种情况下,验证只检查设计是否准确地表述了设计人员对规范的理解。验证无法检查出设计人员对规范的错误理解。第1 章 什么是验证5任何人的介入都会产生不确定性和不可重复性。以下方法可以
11、减少人为错误出现的可能性:自动化、防差错技术或冗余。1.4.1 自动化消除人为的错误自动化显然可以消除人为的错误。虽然自动化的过程没有人的介入,但并不是所有的过程都可自动化,特别是一些没有很好定义、要求人的智彗和创造性的过程,例如硬件的设计。1.4.2 防差错技术确保人的介入简单安全另一种防止人为错误的办法是把人的介入简化成简单、安全的步骤,人的介入仅仅是为了获得预期输出所要求的特定序列或步骤。这种方法在全面质量管理中称为“防差错技术”(Poka-Yoke),它离全自动的过程只有一步之遥。和自动化方法一样,它需要仔细定义的过程和标准的变换步骤。验证过程至今仍然是一种技术,并没有预定的步骤。1.
12、4.3 冗余让两个人相互检查对方的工作最后一种消除人为错误的办法是冗余。它是最简单的方法,也是代价最高的方法。冗余要求每个变换资源都有一个备份。每个由人完成的变换都由另一个人独立验证,或者由两个人分别完成变换,并比较是否产生了相同或等价的结果。这种方法常用在要求高可靠性的场合,例如航空或空间系统中。在工业界的某些场合,重新设计并替换有缺陷产品的代价比冗余的代价更高,例如ASIC设计,这时也采用冗余法。应该由不同的人负责验证图1.5显示了恢复路径模型,其中使用了冗余方法来防止对模棱两可的设计规范的错误理解。在硬件设计的过程中,变换就是根据设计规范编写RTL代码,这意味着应该由不同的设计人员负责验
13、证。图1.5 冗余可以在不确定的情况下保证验证的准确性编写测试平台HDL 模型的功能验证(第二版)61.5 验证的对象是什么选择公共起点和恢复点来确定验证的对象,通常这些选择由验证所使用的工具决定。知道这些点位于什么阶段对于理解正在验证哪种变换非常重要。形式验证、模型检查、功能验证和规则检查具有不同的公共起点和恢复点,因此验证的对象也不同。1.5.1 形式验证形式验证并不能消除对编写测试平台的需要最初,形式验证很容易被误解。不了解形式验证的工程师会把它想像成一种可以从数学角度验证设计正确性的工具,因此就不需要编写测试平台了。只要理解了什么是形式验证恢复路径的终点,就可以理解形式验证的对象是什么
14、。形式验证的应用可以分为两大类:等效性检查和模型检查。1.5.2 等效性检查等效性检查对两个模型进行了比较图1.6是等效性检查的恢复路径模型示意图。形式验证从数学的角度证明了变换过程的起点和输出在逻辑上是等效的,因此变换保持了原来的功能。图1.6 等效性检查的路径两个网表的比较在大多数情况下,等效性检查用来比较两个网表,以保证网表的后处理没有改变电路的功能,其中的后处理包括插入扫描链、时钟树综合或手动修改网表等。等效性检查可以检测出综合软件的缺陷等效性检查的另一种常见的用法是验证网表和原始RTL代码的一致性。如果完全信任综合工具,这种验证就没有必要了。然而,综合工具是一个巨大的软件系统,它依赖
15、于算法的正确性和库的信息。事实证明它容易产生错误。等效性检查可以确保综合软件的正确性。在极少数情况下,也使用等效性检查来验证RTL 代码和相应门级设计的一致性。文本编辑器仍然是最伟大的设计工具!第1 章 什么是验证7有时我们也使用等效性检查来检验两个RTL设计在逻辑上是否一致。等效性检查可以用来避免运行冗长的仿真,例如,为获得更好的综合效果对源代码做一些小的非功能性修改,或者把设计从一种HDL 语言翻译成另一种语言。等效性检查曾经找到过算术运算中的缺陷等效性检查可以用于验证逻辑综合变换。它仅仅比较组合逻辑和时序逻辑,并不关心为满足严格的设计约束所进行的面向特定工艺的功能映射。数字设备公司(DE
16、C,现在已合并到HP公司)的工程师们曾经用等效性检查发现过一个设计综合出错的结果。该设计使用了一个可综合的运算操作,这种运算在处理48位以上的数据时会发生错误。虽然在这个运算操作的文档里明确指出了这个缺陷,即它不保证可以处理48位以上的数据,但是综合工具并不知道这个文档指出的缺陷,因此产生了错误的逻辑。等效性检查发现了这个难以用门级仿真发现的问题。1.5.3 模型检查模型检查证实了关于设计行为的断言模型检查是形式验证技术的一个新应用,它证明或否定了设计的断言或特征。例如,可以检查设计中的状态机是否有不可到达的状态或孤立状态。更强大的模型检查器可以判断状态机是否会发生死锁。与接口相关的断言是另一
17、类可以采用形式化验证的断言。关于设计接口的断言可以采用形式描述语言来描述,然后由工具来证明或否定这个断言。例如,一个断言可能表明:如果输出了ALE信号,那么 DTACK信号或ABORT 信号会随后输出。最困难的是确定要证明哪些断言,并正确地描述这些断言图1.7所示的是模型检查的恢复路径模型。模型检查技术的最大障碍是根据对设计的理解判断应该验证哪些断言。在这些断言中,只有一部分可以被证明。现在的技术还不能证明设计的高层次断言,即不能确定是否正确实现了复杂的功能。例如,如果能够证明以下断言会是很好的事:如果设定了一组特殊的寄存器,异步转移单元(ATM)将按某种次序产生一组输出。不幸的是,现在的模型
18、检查技术还没有达到这个水平。图1.7 模型检查路径编写测试平台HDL 模型的功能验证(第二版)81.5.4 功能验证功能验证验证了设计意图功能验证的主要目的是确定一个设计是否实现了预定的功能。图1.8所示为功能验证路径模型。功能验证检验了设计及其规范的一致性。如果没有功能验证,设计人员只能主观地认为自己没有错误地理解设计规范的意图,从设计规范的文档到RTL 代码的变换是正确的。图1.8 功能验证路径可以证明缺陷存在,但无法证明缺陷不存在除非设计规范用具有精确语义的形式描述语言编写,否则就不可能证明一个设计与设计规范相符,这一点非常重要。设计规范的文档是由设计人员用自然语言编写的,这些设计人员的
19、表达与交流的能力各不相同。任何设计文档都需要理解。功能验证可以展示一个设计和设计规范相符,但不能证明这一点。我们只要找到一个不同点,就可以很容易地证明一个设计与预期功能不相符,但反之却不成立:没有人能证明没有不同点,就好像没有人能证明会飞的驯鹿和UFO 不存在一样(但是只要找到一只会飞的驯鹿和UFO,就可以证明相反的观点)。1.6 功能验证的方法功能验证可以通过以下三种方法实现:黑盒法、白盒法和灰盒法。1.6.1 黑盒验证黑盒验证不能检查或了解设计的内部采用黑盒法进行功能验证时不用关心设计是如何实现的,所有的验证都可以通过接口完成,无需直接访问设计的内部状态,也不需要了解设计的内部结构和实现方
20、法。这种方法显然缺乏对设计的可控性和可观测性,很难设置一种状态或隔离某种功能。黑盒法很难观测和输入相对应的输出,也难以对故障源定位,尤其是在故障的产生时刻和它在设计的输出端表现出来的时刻之间具有较长的时延时,更加难以定位。即使存在这种语言,设计人员也必须表明这种描述精确地描述了设计意图,而这只能通过某种更高层次的不确定的规范来解释。第1 章 什么是验证9测试用例和实现方式无关黑盒法的优点是它不依赖于任何特定的实现方式,例如,单片ASIC、RTL代码、门、多片FPGA、电路板或纯软件实现。黑盒功能验证方法是真正的一致性验证,不管具体的实现方式,它只检验设计是否实现了规范的要求。我的母亲非常熟悉黑
21、盒法:为了防止我们猜测圣诞礼物的内容,她从不在预先包装好的盒子上写上姓名。到了圣诞节,她不能打开它们,但又不得不分辨出每个盒子里装的是什么,然后才能知道这个盒子应该给谁。她曾经数次搞错了对象,成为节后我们的笑料。黑盒验证很难控制和观测特定的功能纯粹的黑盒法在现在的大规模设计中并不实用。一个数百万门的ASIC具有太多的内部信号和状态,从外部很难有效地验证所有的功能。深嵌在设计内部的关键功能很难控制和观测,而且设计的缺陷也不会轻易在ASIC的输出端口出现失效的征兆。例如,我们使用图1.9的黑盒ASIC级测试平台验证一个轮转式仲裁器。如果仲裁器在实现时对各个输入端没有平等对待,在输出端会有什么征兆?
22、这种缺陷只有通过比较每个通道的实际吞吐量和理论吞吐量,经过多次长时间仿真的性能分析后才能发现。图1.9 底层功能的黑盒验证1.6.2 白盒验证白盒验证了解并控制设计的内部细节从这种方法的命名就可以看出,白盒方法对设计的内部结构和实现具有完全的观测能力和控制能力。这种方法的优点是可以迅速设置感兴趣的状态和输入,或隔离一种特殊的功能,然后随着验证的进行观测输出结果,检查任何不同于预期行为的差异。白盒验证与特定的实现相关连然而,这种方法是与特定的实现紧密相连的。设计的修改意味着对测试平台的修改。在改变实现方式或重新设计后,这些测试平台将无法用于门级仿真。这种方法还需要了解设计的实现细节,这样才能设置
23、要仿真的关键状态,确定要观测的结果。这让我的妻子很生气,因为她喜欢摇晃所有贴着她的名字的盒子。编写测试平台HDL 模型的功能验证(第二版)10可以使用白盒验证来增强黑盒验证白盒验证是对黑盒验证的有力补充。它可以确保底层的特定功能实现的正确性,例如,计数器到达翻转值后是否翻转,数据路径是否已进行了适当的调整和排序。白盒方法可以只使用黑盒或灰盒的激励来检测功能的正确性。如图1.10所示,在图1.9的ASIC级黑盒验证环境中增加了白盒检查以验证仲裁器的功能。只要仲裁器的实现存在着不平等的情况,白盒检查就可以报告这个缺陷,这种错误报告方便了故障源的识别和定位。经过三个昼夜的仿真,通道吞吐量之间2的差异
24、可以很容易地解释为随机误差。图1.10 黑盒环境中的白盒检查白盒方法用于系统级验证纯白盒验证方法常用于 SoC设计和系统级的验证。这里的系统由若干独立设计和验证过的模块构成。系统验证的目的是验证系统的功能,而不是再次验证各个模块的功能。由于系统的状态数量非常多,并且很难设置我们感兴趣的状态,因此系统级验证通常把系统看做是由很多黑盒构成的一个集合。每个模块看做一个黑盒,但整个系统是一个白盒,具有完全的可控性和可观测性。1.6.3 灰盒验证灰盒验证是就设计实现的相关性在黑盒验证和白盒验证之间的折中,前者不能控制设计的所有部分,后者不具备可移植性。测试用例可能与其他实现方式无关像黑盒验证方法一样,灰
25、盒方法通过设计的顶层接口进行观测和控制。同时,针对特定实现的特殊功能进行专门的验证。对不同的设计实现可以进行相同的验证,但这种验证不会比其他黑盒验证更关注特殊功能。典型的灰盒测试用例可以增加测试覆盖率,输入激励被设计来执行特定的代码行或在设计中创建一系列的特定状态。如果设计结构(不是功能)发生了变化,这种测试用例仍然可以工作,但对提高测试覆盖率则不再有效。增添设计功能以提高可观测性和可控性典型的灰盒方法是对设计做某些非功能性的修改以提高可观测性和可控性,例如,增加可以通过软件访问的寄存器以控制或观测内部状态、加速实时计数器、强制引发异常或修改待处第1 章 什么是验证11理数据的数量以减少验证时
26、间。这些增加的寄存器或功能在正常的操作中不会起任何作用,但在首个原型系统的集成阶段非常有用。不能在设计阶段并行进行白盒验证只有黑盒和灰盒方法才可以同时进行行为模型的功能验证和设计的实现。由于事先不知道任何设计实现的细节,因此只能选择这两种方法。1.7 测试与验证的比较测试验证了制造过程测试很容易与验证相混淆。前者的目的是验证设计是否被正确地制造出来,后者的目的是确保设计实现了预期的功能。图1.11所示的是测试与验证的恢复路径模型。测试检验了提交制造的网单和制造的芯片之间的一致性。图1.11 测试与验证的比较测试验证了内部节点可以翻转测试的过程是通过测试矢量进行的。这些测试矢量的目的并不是要执行
27、某种功能,而是让设计内部的物理节点发生从 0到1或者从1到0的变化,同时能从外部观测到这种变化。测试的物理节点数和总的物理节点数之比称为测试覆盖率。为了在测试矢量最少的情况下达到最大的测试覆盖率,测试矢量通常通过一个称为自动测试模式生成(automatic test patterngeneration,ATPG)的过程自动产生。测试的完整性取决于内部节点的可观测性和可控性测试覆盖率取决于将内部节点设置成1或0,然后从外部观测这些节点是否真正被设置成1或0的能力。有些设计只有非常少的输入和输出,但却有大量的状态,因此需要很长时间才能控制或观测所有的内部节点。手表就是一个最好的例子:手表有3或4个
28、输入端(位于表盘周围的按钮),少量的输出端(显示器上的数字和符号)。如果手表具有秒表和日历功能,它就有数十亿种可能的状态组合(把数百年分成毫秒计),需要几百年才能让这样一个设计遍历完所有可能的状态。编写测试平台HDL 模型的功能验证(第二版)121.7.1 基于扫描的测试将所有寄存器链接成移位寄存器可以增加可控性和可观测性幸运的是,基于扫描的测试技术使这个问题变得易于处理了,它把设计中的所有寄存器连接成一个长的链。在正常模式下,寄存器正常工作,好像扫描链并不存在,如图1.12(a)所示。在扫描模式下,寄存器好像一个长的移位寄存器,如图1.12(b)所示。要测试具有扫描链的设计,应把被测单元置于
29、扫描模式下,然后通过扫描链把输入模式移入所有的内部寄存器。随后将被测单元设置成正常模式,并输入一个周期的时钟信号,将正常操作的结果送入寄存器中。最后把被测单元再次设置成扫描模式,并将结果从寄存器中移出(同时把下一组输入模式移入到内部寄存器),与预期的结果进行比较。(a)正常模式 (b)扫描模式图1.12 基于扫描的测试基于扫描的测试对设计有一些限制这种技术增加了设计的可控性和可观测性,也提高了测试覆盖率。为了能够插入扫描链并自动生成测试模式,必须对设计加以限制,这些限制包括但不局限于:全同步设计、没有导出时钟或门控时钟、使用同一个时钟沿等。关于可测性设计的问题太大、也太复杂,不在本书讨论的范围
30、之内。详情可参阅有关书籍与论文。基于扫描的测试的优点远远超过了其限制的缺点刚接触这种技术的硬件设计人员会反对这种限制,他们只看到眼前芯片面积的增加和他们所喜欢的设计方法被放弃。然而,当设计可以容纳一条或多条扫描链,当仅仅按一个键就可以实现测试模式和高测试覆盖率时,这些增加的面积和设计工作量就可以忽略不计了。对产品投放市场的信心的增强和所节省的时间带来的好处远远超过了基于扫描的设计带来的成本增加。1.7.2 面向验证的测试为满足可测性的要求,有可能需要修改设计,那么为满足验证的需求而修改设计是否合理呢?Abramovici,Breuer and Friedman,Digital System T
31、esting and Testable Design.IEEE ISBN 0780310624.Cheung and Wang,“The Seven Deadly Sins of Scan-Based Design”,Integrated System Design,Aug.1997,p50-56.第1 章 什么是验证13在制定规范期间必须考虑验证既然功能验证的工作量超过了电路设计的工作量,因此用额外的设计来简化验证是非常必要的。就好像在设计中加入扫描链增加了可测性、却没有增加设计的功能一样,为设计增加非功能性的结构来简化验证也应该是一个标准的设计过程。这种方法要求在项目的开始阶段,即规范的制
32、定阶段就考虑验证的需求。在制定设计的结构时不仅要回答“要做什么”,还要回答“怎么验证”。典型的面向验证的技术包括恰当定义的接口,在功能上明确区分相对独立的单元,提供额外的可以通过软件访问的寄存器以观测和控制内部节点,提供可编程多路复用器以隔离或旁路某个功能单元。1.8 设计与验证的重用今天,设计的重用已经成为了设计过程中的一部分,它是缩小在单个芯片上能制造出晶体管的数量和工程师能设计的晶体管的数量之间的差异的最好办法。这个差异也称为“产能差”。最初设计重用被认为是很容易实现的方法,但实践证明这是难以解决的。1.8.1 重用涉及到信任你不会使用你不信任的东西设计重用最主要的障碍是文化方面的。设计
33、人员一般不愿意把一个不了解的设计加入到自己的设计中。他们不相信别人的设计会像自己的一样好、一样可靠。设计重用的关键是获取他们的信任。像质量一样,信任不是可以加入到设计中的某些东西。它必须是内在的,贯彻在整个设计过程中。它只能在使用可重用的设计的过程中获得:提供设计服务、与客户建立联系。只有建立了信任关系,设计重用才能继续下去。恰当的功能验证论证了设计的可信度可信度可以通过恰当的验证过程来证明。通过向用户展示已经详细深入地按照设计规范进行了验证,可以迅速取得用户的信任。功能验证是证明设计已经满足、甚至超过了工程师能完成的类似设计的品质的惟一方法。1.8.2 面向重用的验证可重用设计的验证必须满足
34、更高的置信度在创造一个新的设计时,设计人员会对自己的能力充满信心,也会信任所做设计的正确性。功能验证用来验证这个观点,以及验证设计的薄弱之处。如果要重用一个设计,只能依靠编写测试平台HDL 模型的功能验证(第二版)14功能仿真来建立这种自信和信任。因此,可重用设计必须经过比专用设计更严格的验证,以满足更高的置信度。所有的功能、配置和使用情况都需要验证为了满足各种环境和应用的需要,可重用的设计往往是可配置或可编程的,因此必须验证各种可能的配置和使用环境。设计的所有功能都需要验证并演示给用户。1.8.3 验证重用测试平台中的模块也可以重用正如设计可以重用一样,测试平台的部分模块也可以重用。例如,图
35、1.13(a)中用来验证设计模块的总线功能模型(BFM)也可以用来验证图1.13(b)中使用该模块的系统。(a)模块级测试平台 (b)系统级测试平台图1.13 在系统级测试平台中重用模块级测试平台的BFM验证重用有自己的需要有不同程度的验证重用,有些很容易实现,有些则面临着与设计的重用相同的问题。在不同的测试平台和测试用例之间为相同的设计重用BFM是非常简单的,只需构造一个合适的验证环境。在同一个设计的不同版本之间重用测试平台的模块和测试用例存在一些困难,例如,无法验证新版本的新功能。在不同的项目之间或不同的抽象层次之间重用设计面临更多的问题,包括验证模块本身的设计等。复用并不是重用复用(Sa
36、lvage)指重复使用已有测试平台的一部分,这一部分测试平台并不是专门为重用而设计的。复用模块的可用性在很大程度上取决于要验证的设计和原始设计的相似程度。例如,用来验证接口模块的BFM可能就不适合验证一个使用接口模块的系统,如图1.13(a)所示。模块级和系统级测试平台对BFM的需求并不相同模块级验证必须检验实现接口协议的状态机和译码器,这种验证需要使用事务级BFM,并能够控制协议信号,改变时序或注入协议错误。系统级验证要检查接口模块后面的高层功能,它要求能够将高层数据封装到接口事务中,它所要求的可控性位于比验证接口模块的信号更高的层次。第1 章 什么是验证151.9 验证的成本验证是不可避免
37、的,它总是需要耗费很长的时间、人力和物力。验证不能直接产生任何收益,最后销售并获利的是经过验证的设计,而不是验证本身。然而,验证是不可缺少的,设计必须保证功能正确并能为客户带来利润才能最终投入市场并获益。随着错误的减少,寻找错误的时间越来越长,成本越来越高实际上,验证是一个永远也不会结束的过程。验证的目标是确保一个设计没有错误,但这个结论是无法证明的。验证只能检测出错误的存在,而不是证明并不存在错误。如果有足够多的时间,错误总是能被找到。这样问题就出现了:是否值得花费很大的代价去寻找这些错误?随着用在验证上的时间越来越多,相同的开销所能找到的错误越来越少。随着验证过程的深入,所得到的回报越来越
38、少,找到剩余的错误的代价也越来越高。功能验证和统计学上的假设检验类似。需要验证的假设是:“我的设计功能是否合格?”答案可以是“合格”或“不合格”。但任一种答案都有可能是错的,这些错误的答案可以分为第一类错误(伪错,false negative)或第二类错误(漏报错误,false positive)。必须避免“漏报错误”图1.14是可能发生的各种错误情况的示意图。第一类错误,即“伪错”,是比较容易发现的一种错误。这种情况表示验证过程发现了一个实际上并不存在的错误。发现这种错误后,通过修改验证过程,将判决结果从“不合格”改成“合格”就可以避免这种错误。第二类错误是严重的错误:验证过程漏掉了一个错误
39、。在第二类错误,即“漏报错误”的情况下,错误的设计不知不觉地通过了检验,这将会带来潜在的风险。图1.14 第一类错误和第二类错误在确定存在潜在的、灾难性的后果方面,美国食品及药物管理局面临着第二类错误的风险。例如,临床实验结果正确是否意味着一种危险的药剂可以投放市场?错误的设计被放行的后果可能导致产品被召回,也可能导致空间探测器着陆后完全失效。编写测试平台HDL 模型的功能验证(第二版)16随着公司的未来可能面临的潜在风险,验证过程中一个价值为64 000美元的问题是:“验证到什么程度才足够?”本书所讲述的功能验证过程和下一章介绍的一些验证工具将回答这个问题。验证过程中一个价值为六千四百万美元
40、的问题是:“什么时候才能完成验证?”尽管不能精确地估计时间,但确定正在进行验证过程的哪一步比估计验证所需的时间要容易得多。第3章介绍的验证规划过程使验证主管可以更好地估计完成任务的时间和效果。1.10 小结验证是一个过程,而不是一系列测试平台的集合。验证独立于设计规范及其实现方式。要理解这种独立性,必须明白到底要验证什么?验证可以在不同的设计层次进行,不同的层次设计其可测程度也不相同。笔者更喜欢使用“黑盒法”,因为用这种方法可以写出可移植的测试平台。应该根据需求来选择灰盒测试平台或白盒测试平台。在设计的开始阶段就应该考虑验证的问题。如果一个功能难以验证,那就应该修改设计,增加这个功能的可测性和
41、可控性。第2章 验 证 工 具正如上一章所提到的,自动化是用来提高效率和可靠性的一种方法。本章介绍功能验证环境中使用的工具。这些工具,例如仿真器,对于功能验证起着至关重要的作用。其余的工具,例如Lint 或代码覆盖工具,使一些单调的验证工作自动化,并增加了功能验证结果的可信度。本章没有提到所有的工具,也没必要使用这里提到的所有工具没有必要使用本章涉及的所有工具,随着新的专用和通用自动化验证工具不断地涌入市场,我们所能列举的工具是有限的。作为一名验证工程师,你的工作是使用必要的工具来确保验证过程的结果没有第二类错误,即漏报错误。作为项目主管,需要在预算之内按期交货,你的职责是为工程师提供合适的工
42、具,使他们高效可靠地完成工作。最重要的是,你还需要判断寻找功能错误的成本何时将超过所带来的效益。这些工具能提供信息,帮助你判断何时能达到这个目标。本书不倾向使用特定的商业化工具笔者在这里提及了一些商业工具的名称,仅仅是因为需要,并非是因为个人的倾向性。这里,向未提及的同类产品的供应商道歉,未提及的原因并非是因为产品等级的差别而是由于笔者知识有限。此外,所提及的所有商标及服务标识,无论注册与否,其所有权都归属各自的厂商。2.1 l i n t 工具l i n t 工具可发现程序员易犯的一般性错误术语“lint”来自于一个UNIX工具的名字,该工具可以解析C程序并报告错误的用法和潜在的问题。当C程
43、序设计语言被Dennis Ritchie开发出来时,它并不包含一些后续版本(例如ANSI-C、C+)或其他强类型语言(例如Pascal、ADA)使用的检错结构。lint发展成为一种用来识别程序员的一般性错误的工具,使人们更快、更有效地发现错误,而不是等到程序执行出错时再去发现问题。lint能识别出真实的问题,例如,自变量和函数调用之间的类型不匹配,或自变量数量的不匹配,如例2.1所示。这段源代码在语法结构上是正确的,并且在gcc版本2.8.1中也不产生任何编译错误或警告。编写测试平台HDL 模型的功能验证(第二版)18例2.1 语法结构正确的K&R C源代码但是,例2.1 出现了两个不合理的严
44、重错误:1.my_func 函数调用中只有一个参数,而不是两个。2.my_func 函数调用中的第一个参数是整数值,而不是整数指针。能够比执行程序更快地发现问题如例2.2所示,lint能识别出这些问题,使程序员在执行程序前及时更正以避免程序运行失败。在执行程序时诊断这些问题需要花上几分钟的时间运行调试器,而使用lint只需要几秒钟,显而易见,后者效率更高。例2.2 例2.1的l i n t 输出l i n t 工具是静态的lint工具和其他验证工具相比有极大的优点:不需要激励,也不需要描述期望的输出,完全静态的检验、lint工具内嵌了期望值。2.1.1 l i n t 工具的局限性l i n
45、t 工具只能识别出某些类型的问题lint 也能识别出其他潜在的问题。在修改了例 2.3 中的所有错误后,lint 仍然报告函数my_func的调用存在问题:返回值总是被忽略。lint工具不能识别出所有源代码中的问题:它只能通过静态推理代码结构来发现问题,不能发现算法和数据流中的问题。第2 章 验 证 工 具19例如,在例2.3中,lint没有意识到未初始化的my_addr变量将在函数my_func中递增而产生随机结果。lint工具类似于拼写检查程序:能识别拼错的单词,但不能识别是否用错了单词。例如,本书中可能有多处将“width”误用为“with”,这样的错误便不能被拼写检查程序(或lint工
46、具)发现。例2.3 功能正确的K&R C源代码许多伪错出现在报告中lint工具的局限性还在于经常报告伪错。为了避免第二类错误 漏报错误,lint工具经常过于谨慎地报告出实际不存在的错误,从而导致许多第一类错误 伪错。报告中的此类问题常使设计者浪费时间和精力,也因此导致一些人放弃使用lint 工具。仔细过滤错误信息使用lint工具时应该过滤其输出的伪警告和伪错误,这可以减少寻找实际不存在的问题的几率。更重要的是,这降低了输出的混乱程度,即伪错以外的真正错误被忽略的可能性降低了。同理,真正的错误应该被强调,所以在写这样的过滤器时应非常谨慎以保证真正的错误不被过滤掉。命名规则可以帮助输出过滤恰当定义
47、的命名规则可以有效地确认某个警告是否重要。例如,在例 2.4 中,其名称以“_lat”结尾的信号推论出锁存器的报告是伪警告,其他的报告可视为真正的错误。例2.4 一段假设的Ve r i l o g l i n t 工具的输出不要关闭检查功能过滤lint工具的输出比在源代码或命令行里关闭检查功能更有优势。因为检查可能在需要检查的时间段内保持关闭,导致忽略真正的问题。当新的源文件加入到项目中时,一些看似不相关的检查有可能变得非常重要。编写测试平台HDL 模型的功能验证(第二版)2 0在编写代码时就使用l i n t显然,最好的办法是在问题刚产生时就解决它,所以应该在写源代码的同时就运行 lint。
48、如果等到大量代码编写完成后再进行lint,那么夹杂着伪错的大量报告将难以处理。因此当程序员对编写的代码仍保持着清晰的思路时,是判断报告真伪的最好时机。强调编码规则通过使用用户定义的规则,lint过程强化了编码规则和命名规则。所以为了保证代码能符合可读性和持续性的要求,lint应该成为整个过程中不可缺少的一部分。2.1.2 Li n t Ve r i l o g 源代码Li n t Ve r i l o g 源代码能检查出一般性错误Lint Verilog源代码能保证所有数据都经过了适当的处理,没有意外的删减或增加。例2.5中所示的Verilog 模型看似正确,编译也没有出错,但在Verilog
49、-95的一些情况下会产生意外的结果。例2.5 存在潜在问题的Ve r i l o g代码在大多数情况下,错误可能并不明显上例中的错误在于:赋值过程的输出信号“out”和常数“bz”之间的位宽不匹配,未约束常数的位宽为32位,但输出的宽度根据使用对象的不同而不同。只要输出数据的宽度小于或等于32,程序将正确运行:常数的值将被截断到与输出位宽相匹配。但是,在Verilog-95中,输出宽度大于32位时会发生错误:Verilog-95在常数中补零以与输出的宽度相匹配,因而导致发生错误。低 32 位被置为高阻态,而所有其他高位被置为 0。Verilog-2001 已经修改了这种错误。一般仿真不能发现此
50、类错误,除非使用了大于32位的配置,并且产生的错误结果恰好被观察到,然而lint 工具总能在几秒之内发现这类错误。2.1.3 Li n t VHD L 源代码由于VHDL是一种强类型的语言,所以它不需要像Verilog那么多的lint。VHDL编译器执行了许多本应由lint 工具执行的检查,尽管如此,最好还是使用lint 工具来识别潜在的错误。见附录A:编码规则。第2 章 验 证 工 具2 1l i n t 能发现额外的多驱动器例如,使用STD_LOGIC类型容易引起一种常见的错误。由于STD_LOGIC是一种判决类型,所以STD_LOGIC信号可能有一个以上的驱动器。在为硬件建模时,多驱动器