众所周知,功能验证在芯片的整个设计周期中占用的时间最多。尽管目前有许多技术可用于减少验证时间,但最终应当如何选择?答案并不简单明了,而且经常令人迷惑并要付出高昂的代价。
一个项目中需要使用的工具和技术必须在设计周期的初期就确定下来,以便获得新验证方法费用预算的准确信息。经常有公司因为错误估计了运转这些新型工具和技术所需的设计和技术的复杂性而浪费大量的资金和资源。
产品的抽象级越高,越容易设计;同样的,抽象级越高,越容易犯严重的错误。一个架构上的缺陷可能会导致整个芯片的损害,而在门级网表中的连线错误可以通过重制解决。
例如,Verilog为设计者提供了一种相对容易的接口,以便他们在相当抽象的层次上进行设计。当设计曾经作为制约性的瓶颈时,Verilog 为设计生产率带来了指数增长,并且大大推动了复杂芯片的发展。但是如果设计者不了解在复杂的设计周期中语言上的细微差别,就很容易犯错。在验证成为瓶颈的今天,同样的观点也适用于许多验证技术和语言。
验证瓶颈
尽管事实表明如今设计生产率的增长速度仍然低于芯片复杂度的增长速度,然而现在需要面对的瓶颈已不再是设计时间,而是验证时间。最近的统计数据表明,对一个复杂逻辑芯片而言,整个产品周期中 60_70% 的时间都用于验证工作。如何使用新的工具和技术对设计中的复杂功能进行验证已经成为缩短总体的产品时间所需要面对的挑战。
由于以下原因,可以说验证瓶颈在某种程度上是设计抽象级逐步提高造成的结果:
1) 在较高的抽象水平上进行设计,易于构建高度复杂的产品功能。设计复杂度的提高造成验证工作的成倍增加;
2) 在设计、转换以及映射到最终产品的过程中,应用更高的抽象级进行设计会带来信息损失和解释错误的问题。例如,采用HDL级设计并将其转换到门级的综合过程,需要进行验证以确保转换的正确性以及使设计意图完全得到体现。提高抽象级还带来了代码解释问题,在仿真时要通过这些代码对设计进行描述,以确保所写的代码真实反映了功能规范。
其它影响验证问题的因素还包括:
1) 由于设计中硬件与软件、模拟与数字等共存而造成的功能复杂度增加;
2) 对系统可靠性的要求增高,使得对验证工作的要求也增加,以确保在系统环境下,芯片功能可以顺利执行。
统计数据表明,验证问题现实存在,而且让公司付出了高昂的成本:
1)由于设计错误造成的芯片缺陷:在需要进行重制的芯片中,有82%是由于逻辑与功能缺陷设计错误。这意味着验证过程没有覆盖边角情况,缺陷一直隐藏在设计过程中直到流片。
2)由于规范错误造成的芯片缺陷:在需要进行重制的芯片中,有47%是由于逻辑与功能规范不正确或不完整,有32%是由于规范发生了改变。
3)重用IP和外来IP的问题:所有失败的芯片中,有14%是由于在重用或外来的IP中存在错误。
4)重制的后果:重制费会高达10万美元,还会延误产品的推出,由于使用这些有缺陷的芯片而导致的系统失败也会增加成本。
为了提高验证生产率,EDA行业提出了一个与解决设计瓶颈类似的解决方案——抽象化的理念。诸如 Verilog 和 VHDL 等高层次的语言被用于验证芯片,这些语言包括各种指令如任务指令和线程指令(fork/join 语句),以及控制结构(while语句)。这提供了更强的数据控制力,以便对所有边角设计进行充分验证。然而,这些指令不能被综合,因此不会被用作实际设计代码的一部分。
随着复杂度与日俱增,能够验证具有不同抽象级的复杂设计的新语言被创建出来,支持这些新的验证语言的技术和工具也随之诞生。
所有这一切意味着芯片厂商必须对新的工具作出评估,必须针对这些新的工具和技术对工程师进行培训,在公司的研发费用成本结构中必须包括新的工具和资源,公司在总体上必须在短时间内克服学习曲线问题,另外,还需要对这些工具进行风险评估,以及考虑新工具与已有技术的集成和协同工作的能力。
验证与确认(Validation)
除了验证问题之外,芯片公司还要面对确认时间问题。Kropf 将“确认”定义为“通过检查实现行为以获得对规范的信心的过程”。在验证和确认之间,有一种观点认为,“确认能够确保这是正确的设计,而验证则是确保这个设计是正确的”;另外一种观点认为,“验证指硅片成为成品之前的测试(Verilog/VHDL 仿真等),确认指硅片成为成品之后的测试(在实验室里测试电路板上的芯片)”。
无论是确认还是验证,若要保证硅片满足规范要求,要完成以下两个步骤:1)通过文件或建模,芯片规范得到了正确的解释;2)以上解释得到了正确的理解与实现(一般是通过 HDL),综合入硅片,并封装成为芯片。
本文认为第二步是验证,第一步是确认。目前业界流行的设计流程如图1所示,此流程可保证以上两个步骤的要求得以满足。根据待实现功能的复杂程度不同,可以跳过一些步骤或者增加一些步骤。例如,如果某一项设计是纯粹面向硬件的,不涉及驱动或软件,那么可以从抽象级3直接跳到抽象级1,锁相环设计即为一例。
当设计按照抽象级逐步推进时,要注意必须一直保持等效性,以确保最低层的抽象级能满足系统规范的要求。例如:
1)当 C 模型被置于一个系统环境并能够满足规范中所描述的所有系统要求时,芯片规范(一般是一个文本文件)与其 C 模型之间就达到了等效。这在实质上是功能等效。
2)通过比较 C 模型与HDL 实现的输出,可以在规范的C 模型与其 HDL 实现之间建立等效关系。在没有 C 模型的情况下,可使用“期望数据模型”。这在实质上也是功能等效。
3)HDL实现与门级(综合后的)之间通过应用“逻辑等效性检验”可以建立等效关系。这时,由于设计采取的形式是纯粹的逻辑门,而且功能能够被表示为逻辑表达式,因此,这在实质上是逻辑等效。
现有验证技术及发展趋势
目前可使用的验证方法及技术如图2所示。
动态功能验证
使用最为广泛的功能验证方法是动态的,之所以被称为动态是因为输入图形/激励信号是在一段时间(几个时钟周期)内生成并应用于设计的,相应结果会被用于与参考/黄金模型进行比较,以检验其与规范之间的一致性。
仿真器通常用于计算所有的信号值,并将其与指定的期望值进行比较。目前,有两类可供选择的仿真器:
1)基于周期的仿真器:这类仿真器不管在时钟周期内发生了什么事情,它只是在每个周期内对单脉冲信号进行一次求值,由于执行时间很短这类仿真器的速度通常很快。
2)基于事件的仿真器:这类仿真器在时钟周期内或者在时钟边界捕获事件,并在设计中传播这些事件,直到系统达到稳态。
随机/定向功能验证
在一个有时间限制的仿真过程中,动态仿真器只能验证芯片的典型行为,而不能验证所有可能的行为,这是动态仿真的主要缺陷。出现这个问题的主要原因是对芯片的定向测试是针对已知的测试空间,而不是未知的测试空间进行的。即使是仅对已知测试空间的测试也要花费很长时间。例如,假设推出每个运算数需要一个时钟,为了验证一个能对两个 32 位操作数进行加和运算的简单加法器的测试空间就需要 232x232个时钟周期。随着逻辑运算越来越复杂,验证空间也会相应增加。因此出现了随机动态仿真,通过为设计提供随机激励信号来增加验证的测试空间,这样能够使验证覆盖的功能空间最大化。但当设计规模很大且非常复杂时,随机测试空间会变得无限。为了解决这个问题,更高级的验证语言,如 Open-VERA、E 与SVL (SystemC 验证库)被推出。这些语言引入了诸如约束随机激励信号、随机激励信号分配与电抗性测试平台等概念。伴随着这些语言的运用,出现了一些用于对其进行解释的工具,如VERA、Specman与 OSCI 内核( Concentric System Studio ,CCSS)。
除了引入随机化功能以外,新的验证语言和工具还通过减少公司在构建不同测试场合/方案所花费的时间,来提高生产率。例如,测试方案可以采用最高的抽象级来编写,并能够通过采用功能强大的面向对象型结构而扩展至任何较低的抽象级。
当应用动态验证时,通常需要估计所覆盖的、可以量化的功能空间,包括:经过验证的代码行数(行覆盖率),经过测试的逻辑表达式个数(表达式覆盖率),一个 FSM 设计中能够
达到的状态数(FSM 覆盖率),在一个仿真运行中可以双向变换的端口及寄存器数目(变换覆盖率),以及设计代码中覆盖的逻辑通道数目(通道覆盖率)。以上可以使用 Code Coverage 及 Lint 工具来实现。
断言
设计者将断言用作一个占位符,用来描述与设计相关联的假设及工作特性(包括暂时的特性)。如果设计满足或未满足规范或假设,则断言将会在一个动态仿真过程中被触发。断言还可在形式/静态功能验证环境中使用。
混合功能验证
在该方法中通常执行动态仿真,仿真结果被用作静态验证的输入。在静态验证过程中,在设计中传播的是逻辑方程式/符号,而不象在动态仿真中那样传递数值。这种方法虽然不像形式验证详尽周全,但却具有比纯动态仿真更高的效率。
静态功能验证
在静态功能验证中,不向设计施加输入激励,而是将设计映射在一个图形结构中,用双择判决图(BDD)或其他数学表示方法来描述所有时间周期内的设计功能。利用这种图形结构来证实或反驳属性可以验证这些数学表达式,这是通过顺着或逆着信号流来传递数值,以确定数学结构中的矛盾式来完成的。
现有的工具通过以下两种方式来满足静态验证市场的需求:
1) 使用断言:这是在模型/设计当中规范并公式化的设计约束(使用SystemVerilog、Open-VERA、Verilog和VHDL等设计/验证语言)。
2) 使用属性:这允许使用属性语言(如PSL和Sugar)对属性进行规范。
等效性验证
为了确认门级表示法与HDL实现是相同的,需要实施等效性检验,使用匹配点并比较这些匹配点之间的逻辑。检验中会生成一个数据结构并比较在相同的输入模式下得出的输出数值模式,如果这些输出数值模式不相同,那么表示法(这里指门级和RTL级)就不是等效的。当表示法中的一个经过了某种类型的变换时,等效性检验有时会在两个门级网表或两个RTL级实现之间进行。
造成设计表达式差异的一些实际原因包括:
1) 综合算法/探索式方法:根据对综合工具的约束条件(区域、时间、功率)不同,综合工具会对逻辑运算进行优化,以得到适当的门级表式。为此,综合工具将采用探索式方法和逻辑最小化算法。
2) 抽象级:在采用HDL来实现设计时,由于语言的局限性或是缺乏(不具备)对综合工具如何解释特定语言结构并将其变换为门级表式的预测能力,因此,HDL实现有可能与设计者意图存在一定的差异。
影响验证技术的趋势和力量
技术视角
设计错误可能出现在模块接口处或是在模块内部,它们最终会集成在一起形成芯片。举例而言,那些在模块级没有被发现的缺陷在应用动态仿真时会在子系统或系统级上显露出来。使用静态功能验证,模块开发的每一步都会得到详尽的验证,从而确保子系统/系统质量和可靠性从根本上得到提高。有人认为,使用静态/形式功能验证,能够更快地找到更多的缺陷。
另一方面,使用静态功能验证也存在以下缺陷:
1)现有的工具只能在模块级运行;
2)通常不能处理大型设计(一般只能处理100~150K的门电路);
3)不能处理高度复杂的设计;
4)现有的形式验证工具有时会出现时间无限的问题(这主要是因为它们往往是基于一套探索程序,而不是任一算法)。这意味着形式功能验证在一些情况下可能会比动态仿真花费更长的时间;
5)设计必须被写为可综合的RTL形式。
除了上述技术上的挑战外,基于断言的形式功能验证的两个竞争标准(PSL对SystemVerilog)也带来了额外的问题。目前倾向于将静态功能验证方法用于验证足够成熟以备综合的模块,动态验证(随机和定向)用于严格验证集成前的模块。
目前,动态仿真还将继续主宰功能验证领域,直到形式验证工具提供一种更成熟的方法。
语言视角
可以观察到这样一个趋势,就是将设计和验证语言结合在一起。这将极大地促进生产率,改进系统可靠性以及提高设计质量,因为使用多种工具和语言引发的不明确和误解问题将得到消除。
在这一结合实现之前,公司要继续依赖现有的高级设计语言(Verilog和VHDL),并选择是使用专有验证语言(Open-VERA、E等),还是过去流行的Verilog和VHDL 。
SystemC与其他高级设计描述语言在设计流程中扮演着重要角色,其中涉及硬/软件折衷以及在硬件上运行软件的设计(如SoC)。另外,它们也可用于架构建模及确认,当可以为应用事务模型的验证使用架构模型组件时,也可以使用 SystemC。
选择正确的验证方法的标准
在当前缩短上市时间和迫切要求低成本的环境下,工程师正在设法解决设计复杂性问题。那些在新技术上投入更多研发精力的公司,其研发费用的使用更有效率,产品上市时间更短,公司成长更快,盈利更高。另外,公司必须在其特有需求与核心价值的基础上评估方法和技术。在将新技术引进其工具流程时,它们应当考虑以下问题,并做出适当的权衡。
1)在某个生产线中,公司是市场领先者还是追随者?
2)基础设施、工具和方法是集中式的还是分布式的?
3)新验证技术的评估是针对第一代产品进行的吗?
4)新验证技术对成本和产品上市时间有何直接和间接影响?
5)新的工具能否处理不同的设计能力?
6)工具的易用性如何?
7)可为新的工具提供什么水平的文档和支持?
8)新的工具和方法与公司内部现有的工具和方法之间是否具有互操作性?
9)新工具的投资回报率(ROI)如何?(包括在服务、培训、咨询、计算和人力资源方面的投资)
10)新的工具是否能够支持处于多个不同地理位置的设计?
11)公司需要考虑的问题中,最为重要的问题之一可能是:我们雇用的设计师和验证工程师是否对新的工具抱有成见?(即设计师不愿意学习和接受新的技术)
公司在做出关于工具、语言和方法的决策时可以采用以下介绍的简单权衡方法。
产品视角
主要从事存储器芯片或存储器密集型(相对于逻辑密集型而言)芯片生产的公司讶SRAM和DRAM公司可能根本不需要进行大量的逻辑验证。这些芯片大多是定制的。虽然这些产品中有些规模会很大,但它们的逻辑复杂性并不高,因而不支持在公司内部配备大量逻辑验证工具的计划。不过,存储器密集型设计在其他方面提出了挑战,例如布线、工艺变化以及功率等。
那些制造纯ASIC芯片,在芯片上不运行任何软件的公司可能无须在硬件或是软件实现上进行权衡或是实施测试以捕获运行于硬件之上的软件。例如,只具有硬件的SERDES芯片所要求的验证和建模方法与同时具有硬件和软件的SoC是不同的。
对于拥有多种产品线的大公司来说,验证方法必须满足各种产品的不同要求。
系统视角
过去,逻辑芯片供应商不负责对芯片是否满足参考系统的功能和性能要求进行验证,而如今的系统厂商在批量订货之前都要求芯片供应商实施系统参考验证。这就要求芯片公司在一个它们不熟悉的附加抽象级上对芯片进行建模和验证,这需要架构模型、参考模型、复杂应用级的测试以及精细的测试平台配置。面对这些不同类型的挑战,公司有两种选择,一是采用现有的语言、技术和方法,这将耗费大量的时间和精力;另一种就是采用新技术(如VERA、Specman等)。此外,芯片供应商还必须确保所使用的参考模型和验证套件是在一个与客户的相应模型和套件兼容的环境中完成的,例如,应用客户的软件开发套件(SDK)和仿真器也能够进行同样的测试。
方法学视角
在芯片集成之前,可以将静态功能验证与动态仿真结合起来,在一个高置信度水平上验证模块级的功能。通过确认动态仿真正在持续验证功能空间的主要边角,可以有效地实施系统级验证。
首先执行随机仿真可以在验证的初始阶段发现大量的缺陷,然后对随机模拟加以约束以确定测试空间已经被完全覆盖的做法或许相对容易一些。应考虑在功能覆盖度量上对约束驱动型验证进行细化。功能覆盖率这一术语被用于描述对被覆盖的功能空间进行量化的参数,相反地,代码覆盖率则被用于量化一个给定的测试套件对已实现的设计进行覆盖的程度。定向仿真随后可被用于在验证周期末期覆盖边角测试空间。
断言和属性可在静态功能验证期间起作用(在模块级上),并可在动态仿真环境中被重用(在模块级和系统级上)。如果模块转变为IP,那么断言和属性也是有用的,因为断言将在IP被重用时持续不断地检查其属性。
结语
随着时间的推移,具有更小特征尺寸(90nm 和 65nm)的器件将投产。目前,公司正在致力于解决诸如布线、串扰和软错误的设计问题。一旦这些设计瓶颈得到了解决且随着芯片厂商在越来越小的芯片上封装越来越多的逻辑,验证问题的出现就是意料中的事了。新型工具和方法的不断引进提高了设计生产率。提高设计(SystemC和SystemVerilog)和验证(Open-VERA、E 和 SystemC)的抽象化程度以满足日益增长的复杂度要求是不可避免的。目前从SystemVerilog 的推出能够看到设计和验证语言的融合趋势。
验证持续扮演着重要角色,它能够提高产品质量,使硅芯片一次成功,从而间接影响总体的产品时间。SystemC 和建模语言将继续为逻辑密集型产品提供架构验证。通过使用属性、断言以及推出形式验证工具,生产率得到了进一步提高。但目前工程师仍旧依赖并信任动态仿真,因为它能够验证大型和高度复杂的设计。最终的趋势可能是:形式验证占据主要地位,动态仿真仍用于完整性检查。