欢迎关注个人公众号摸鱼范式
- Fundamentals of Verification
- [239] 定向测试和受约束的随机测试有什么区别?两者有什么优缺点?
- [240] 什么是自检测试(self-checking tests)?
- [241] 什么是覆盖率驱动的验证?
- [243] 功能验证中的测试分级是什么概念?
- [244] 什么是基于断言的验证方法?
- [245] 2*2的分组交换器的spec如下,你将如何验证设计?如何设计激励和检查器?哪些是你需要验证的case?
- [246] 对于一个单端口读写RAM,有哪些场景需要进行测试?
- [247] 单端口和双端口RAM有什么区别?
- [248] 一个简单的带有如下所示的方框图的ALU支持两个4位操作数、一个4位结果总线和进位溢出。ALU支持最多8条指令,使用3位操作码或选择行(S2、S1、S0),解码如下。
- [249] 事件驱动和循环驱动的仿真器有何不同?
- [250] 什么是事务(transaction?)?基于事务的验证有什么有点?
- [251] 你使用或者熟悉的仿真调试工具是什么?
- [252] 我们什么时候需要参考模型来验证RTL设计? 使用参考模型的优点是什么?
- [253] 什么是总线功能模型?
- [254] 如何跟踪验证项目的进度? 使用什么指标?
- [255] 如何衡量验证的完整性,或者说何时/如何验证已完成?
- [256] 什么是GLS?为什么GLS很重要?
- [257] 什么是功率和性能的权衡?
Fundamentals of Verification
[239] 定向测试和受约束的随机测试有什么区别?两者有什么优缺点?
定向测试是一种编写定向测试来验证设计中的每个特性的方法。约束随机测试是一种使用约束随机生成器自动生成激励的方法,该生成器根据设计规范生成激励。下表比较了两者的优缺点。推荐的方法是混合使用这两种方法——约束随机覆盖大部分验证空间,然后指导测试覆盖难以到达的边界条件。
定向测试 | 约束随机测试 |
---|---|
针对每个功能点需要编写一个或者多个测试向量 | 使用激励发生器根据功能点,自动生成符合功能规范的测试向量 |
每次测试都能很简单的进行追踪,具有很好的可视化和可预测性 | 测试是自动生成的,因此只能通过收集覆盖率,并观察覆盖率确保功能的验证 |
当设计特征被充分了解后,定向测试的编写会更加简单 | 开发约束随机测试平台更加复杂,也更加需要经验。需要更多的事件来设计验证平台。 |
对于复杂的设计,定向测试的编写会变得非常困难并且事件消耗会很大 | 与大型测试套件相比,约束随机生成器在开发后更容易维护 |
定向测试编写仅限于通过理解设计规范确定的场景 | 约束随机生成器可以结合随机配置来覆盖更多的场景和特性,从而更好地强调设计,并覆盖手动识别可能遗漏的一些场景 |
[240] 什么是自检测试(self-checking tests)?
自检测试是指在测试结束时通过某种方式来检测测试结果的测试。在测试中,可以通过计算某些内存操作的结果或从DUT(如状态寄存器或任何其他信息)收集结果来预测结果。
[241] 什么是覆盖率驱动的验证?
在覆盖率驱动的验证方法中,验证计划是通过将每个特性或场景映射到一个覆盖率监视器来实现的,该监视器在仿真期间收集覆盖率信息。
- 覆盖率可以是基于样本的覆盖组和基于属性的覆盖的组合。
- 在基于覆盖率的验证中,测试通常使用约束的随机激励生成器生成,测试正确性由功能检查器确保,并为实现的所有监视器收集覆盖率。
- 通常在设计上对随机生成器的多个测试或多个种子进行回归,并合并从每个测试中收集到的单个覆盖率,从而获得累积覆盖率。有时,在设计的一个角边界情况可能不容易被覆盖,使用约束随机激励和可能更好地完成使用一个有指导的测试。
- 覆盖率信息还为测试的质量和生成器中的约束提供反馈,并帮助对约束进行微调,从而有效地随机生成刺激励。
- 由于在这种方法中,覆盖率定义是跟踪验证执行以获得进展和完成的关键步骤,因此确保根据验证计划和设计规范审查覆盖率定义和实现的完整性和正确性是很重要的。
[243] 功能验证中的测试分级是什么概念?
设计的功能验证是通过创建定向测试以及对激励进行不同控制的约束随机激励生成器来完成的。
通过设计验证项目,开发一组测试,该测试套件用于验证设计正确性、发现设计中的bug和收集覆盖率等。
测试分级是一个过程,在这个过程中,单个测试根据不同的标准(如功能覆盖率、发现的bug、仿真运行时、维护的容易程度等)对质量进行分级。
这个过程有助于从测试套件中识别出有效的测试,从而为设计验证开发出最有效的测试套件。
[244] 什么是基于断言的验证方法?
基于断言的验证(ABV)是一种用于捕获特定设计意图的方法。这些断言用于仿真、形式验证,以验证设计实现是否正确。ABV方法可以通过断言的优点来补充其他功能验证方法,从而实现有效的验证。
断言的一些好处如下:
- 断言从源头上检测设计错误,从而提高可观察性和减少调试时间。
- 相同的断言可以用于仿真和形式分析,甚至可以用于仿真。
- 在断言库中有很多通用设计的断言,可以很容易地移植到任何验证环境中。
- 作为属性编写的SystemVerilog断言也可以用于覆盖率(使用覆盖属性),因此有助于基于覆盖率的验证方法。
[245] 2*2的分组交换器的spec如下,你将如何验证设计?如何设计激励和检查器?哪些是你需要验证的case?
SPEC:有两个输入和输出端口A和B,如上所示。每个端口可以接收大小在64到1518字节之间的可变数据包。每个包将有一个4字节的源地址(Source Address)和4字节的目标地址(Destination Address),以及跨包计算的数据和一个4字节的CRC,如下所示。数据包将根据目标地址(Destination Address)被切换到一个输出端口。
对于这类有设计说明的问题,第一步是理解设计说明,并向面试官阐述问题。下一步是确定要验证的场景,并提出验证计划和策略文档。这应该列出要验证的特性/场景,可以使用什么方法来验证(定向/约束随机、覆盖、断言,等等),如何检查正确性等等。此外,还应详细说明如何产生激励以及如何进行检查。
另一个方面是考虑所有的设计特性,并确定需要验证的关键case。现在,让我们试着列出如何验证这个简单的路由器设计
- 以下是一些需要验证的场景:
- 根据目的地地址测试数据包从a端口到两个输出端口的正确切换。
- 测试不同的数据包大小-最小尺寸,最大尺寸和之间的随机尺寸。
- 测试源地址和目标地址的所有可能值。
- 测试不同的数据模式。
- 流包测试(背对背无延迟、周期延迟少、周期延迟大)、大小相同的包流或大小不同的包流。
- 测试CRC功能。
- SA/DA或数据甚至CRC的某些位被损坏的测试。
- 你还能想到什么
- 现在,为了验证上述场景,我们需要设计一个约束随机数据包生成器,我们还需要一个计分板/检查器来检查数据包的正确性和正确的交换行为。如果测试是随机的,我们还需要编写一些覆盖率监视器,以确保上面提到的所有重要场景都得到了覆盖。
- 如果面试官想对你进行更多的测试,那么他也可以继续问你一些问题,要求你写一个SystemVerilog数据包生成器代码或一个检查程序或驱动程序等。
[246] 对于一个单端口读写RAM,有哪些场景需要进行测试?
单端口RAM只有一个读和写端口。因此,它只能在任何给定的时间点进行读或写操作。其他需要考虑验证的设计规范包括RAM大小、地址和数据总线的宽度。基于此,以下是一些需要验证的场景:
- 正确读写行为
- 背靠背读取或写入相同的地址和不同的地址
- 背靠背先读后写同一地址
- 背靠背先写后读同一地址
- 验证内存大小的边界——读和写
- 验证写入数据的所有可能,全0,全1,01交替等。
如果您被进一步要求定义一个验证环境,您可以考虑像上面这样的场景,并定义一个有向或有约束的随机环境是否会更好地工作,以及如何设计激励生成器和检查器。
[247] 单端口和双端口RAM有什么区别?
单个端口RAM只有一个读和写端口。所以它只能在任何给定的时间点进行读或写操作。一个双端口RAM有2个读/写端口,因此允许同时读写。
[248] 一个简单的带有如下所示的方框图的ALU支持两个4位操作数、一个4位结果总线和进位溢出。ALU支持最多8条指令,使用3位操作码或选择行(S2、S1、S0),解码如下。
解释所有需要验证的场景,以确保ALU按照下面的SPEC工作:
以下是需要对这个给定的ALU设计进行验证的场景:
- 通过驱动两个操作数A和B,以及驱动每个操作的选择行,来验证所有单独的操作是否工作(Add、Sub、Increment、AND和OR)。
- 验证如果select行在110-111之间,不发生操作。
- 对于以上每个指令,选择A和B的最小值和最大值以及组合。假设A和B是4位,最大值可能是4 ' b1111
- 验证加法和减法的溢出和下溢情况。如果A和B都是4'b1111,则A加法发生溢出,而如果B的值大于A,则减法发生下溢。
- 验证自增指令的溢出。如果A= 4'b1111,增量应该产生一个0值。
- 一旦验证了各个场景,创建随机的操作码序列,验证一个操作的效果不会影响到下面的操作。检查相同的操作码重复超过一次或不同的操作码以不同的模式重复的序列。
- 为了创建激励,你可以设计一个随机的操作码和操作数生成器以及一个简单的驱动程序。为了检查结果,可以编写一个简单的模型或ALU,并与相同的结果进行比较。
[249] 事件驱动和循环驱动的仿真器有何不同?
事件驱动仿真器对每个事件进行设计评估,采用每个事件并通过设计传播变化,直到达到稳定状态。事件是设计元素的任何输入激励的更改。由于输入和下游设计的信号反馈的到达时间不同,一个设计可能在一个周期内被评估多次。
例如:考虑在时钟上运行的两个触发器之间的逻辑路径。组合逻辑路径可以有多个门和反馈路径。在时钟变化时,当第一个触发器的输出发生变化时,它将应用于组合逻辑的输入,并进一步应用于组合逻辑中不同阶段输入的任何变化,这会触发要评估的特定设计。在这个值稳定下来并且不再在那个时钟周期中变化之前,可能需要进行几次评估。大多数业界广泛使用的模拟器都是事件驱动的,比如:来自Mentor的Questa、来自Synopsys的VCS或来自Cadence的Incisive模拟器。这是因为事件驱动模拟器提供了准确的模拟环境。
基于循环的模拟器没有时钟周期内的时间概念。它们一次性评估状态元素或端口之间的逻辑。这有助于显著提高仿真速度,因为每个逻辑元素在每个周期中只计算一次。缺点是它不能真正地检测信号中的任何小故障,而且它只在完全同步的逻辑设计上表现正常。由于在仿真期间没有考虑设计的时间安排,因此需要再所有的静态时序分析工具对时序进行单独的验证。基于循环的模拟器在一般设计中不太受欢迎,但在一些开发大型设计(如微处理器)的公司中可以定制和使用。
[250] 什么是事务(transaction?)?基于事务的验证有什么有点?
事务是一组低层信息(如一组信号)的高级抽象。当设计在信号级信息上运行时,testbench需要在信号级与设计接口驱动程序和监视器,而testbench的所有其他方面都可以抽象为事务级。在基于事务的验证方法中,testbench以分层的方式进行架构,其中只有较低层的组件在信号级进行操作,而所有其他组件都基于事务进行操作和通信,如下所示。
- 基于事务的验证的主要优点是在一个项目内或跨不同项目的不同验证环境中重复使用事务性接口开发的组件。例如:参考上面的图表,只有driver, monitor 和 responder需要信号级接口。一旦这些组件将信号级信息分组到一个事务中,其他组件(如stimulus generators, slave models 和 scoreboards)都可以对事务进行操作。
- 由于事务性组件需要由模拟器在事务性边界上进行评估,而不是在每个信号变化上进行评估,因此模拟可能会快一些。
- 如果一个设计改变了接口时序,那么只有驱动和监控组件需要改变,其他组件不受影响。
[251] 你使用或者熟悉的仿真调试工具是什么?
这是测试你对不同工具的意识的一个普遍问题。 根据你对各种工具的回答和经验,还可能会询问你在使用这些工具时可能遇到的难易程度/局限性方面的观点。 没有固定的答案,但是常用的模拟器是Mentor Graphics的Questa,Synopsys的VCS和Cadence的Incisive模拟器。 Synopsys的Verdi还是与DVE一起调试的常用工具。 正式工具包括来自Cadence的Jasper和来自Mentor graphics的QuestaFormal。
[252] 我们什么时候需要参考模型来验证RTL设计? 使用参考模型的优点是什么?
参考模型通常是符合spec的不可综合模型,通常使用高级编程语言(例如C / SystemVerilog)编写。 有时会实现参考模型,以便以周期级别的精度或更高级别的边界匹配设计规范。 例如:CPU /微处理器的参考模型应该准确地对指令边界处的状态进行建模,而AMBA总线协议的参考模型应该根据该协议具有精确的周期。 参考模型通常用于检查器/记分板中,以生成给定激励的预期响应,以便可以将其与实际结果或从设计获得的输出进行比较。
[253] 什么是总线功能模型?
传统上,总线功能模型(BFM)是用高级编程语言(如C / SystemVerilog)编写的不可综合模型,该模型可对总线接口的功能进行建模,并可连接到用于仿真设计的设计接口。 在BFM的一侧,将是一个在信号级别上实现总线协议的接口,另一侧将具有一个接口,以支持发送或接收事务。 随着时间的流逝,这个定义已经演变,在诸如UVM之类的方法中,没有像BFM这样的实际组件,他的功能是由一系列组件(如驱动程序,监视器和接收器)实现的。
[254] 如何跟踪验证项目的进度? 使用什么指标?
有很多指标用于跟踪针对计划的验证进度。 验证计划根据定向测试或针对详细方案和特殊情况的功能覆盖率监视器,捕获要验证的功能。 该计划还包括了有关验证环境开发的详细信息,其中包括激励产生和检查方法。 通过跟踪环境开发(激励发生器,检查器,监视器等),测试开发和功能覆盖率监视器开发的完整性,可以在项目的早期阶段跟踪进度。 一旦开发了大多数测试和受约束的随机数发生器,通常就可以在服务器场中以回归方式运行测试,然后根据回归通过率,错误率和功能覆盖率来监视进度。
[255] 如何衡量验证的完整性,或者说何时/如何验证已完成?
当设计的表现与设计规范相匹配而没有任何错误时,可以将功能验证称为完成。为此,我们需要对设计施加激励,以涵盖所有可能的输入可能,并验证设计是否符合规格要求,并且没有任何错误。但是,随着设计复杂性的不断提高,实际上不可能定义所有可能的输入激励方案。此外,资源和时间的限制也使得这种完整的理想定义不切实际。
因此,在大多数项目中,验证的完整性与通过一组度量和过程获得的信心有关,该度量和过程使设计缺陷的风险降至最低。以下是为实现对验证完整性的高度信任而遵循的一些度量和过程:
- 审查验证计划和设计规范,以确保理解并捕获所有细节。
- 确保环境开发方面的适当完整性,测试开发,功能覆盖率根据已有的计划开发。
- 审查测试平台刺激生成器和约束,检查器,断言和覆盖率监视器的实现。
- 确保以回归模式启用所有测试,并且在数周内始终没有失败,所有覆盖率指标均得到满足和理解。
- 确保错误率和未解决的错误为零或者能够追溯,对设计没有影响。
- 重要场景的波形审查。
- 确保进行形式验证(尽可能)。
- 将传入的漏洞和漏洞趋势与过去复杂程度类似的成功项目进行比较。
[256] 什么是GLS?为什么GLS很重要?
GLS是“门级仿真(Gate Level Simulation)”的首字母缩写。 在将RTL代码综合到门级网表之后,运行门级仿真。 GLS构成了验证生命周期的重要组成部分。 除了STA(静态时序分析,Static Timing Analysis)和LEC(逻辑等效性检查,Logical Equivalence Checking)之类的静态验证工具外,它也是必需的,因为STA和LEC不能涵盖/报告所有问题。 GLS主要用于:
- 验证DFT扫描链。
- 验证异步设计中的关键时序路径(STA未完成)。
- 验证复位和上电流程。
- 分析RTL中的X-Sate乐观度。
- 收集开关活动以进行功率估算。
[257] 什么是功率和性能的权衡?
功率和性能是成功产品的两个重要设计要点。 尽管大多数设计在理想情况下都希望以尽可能低的功耗获得尽可能高的性能,但实际上并非总是如此。 动态功耗与CV^2f成正比,其中f为频率,V为电压,C为电容。 因此,通常:
- 降低电压会降低功耗,但会降低性能(随着延迟的增加)
- 降低频率会降低功耗,但会降低性能(时钟变慢)
因此,为了获得最佳性能和功率目标,设计需要选择正确的电压和频率值。
注意:下一章(验证方法)的“电源和时钟”部分(6.3)中提供了有关电源和时钟的更多问题。