CRV(Constrained random verification) & UVM 为功能验证提供支持
1. introduction
硬件结构越来越复杂,诸如直接测试(有很多难以规划出的边界cases)的传统的验证手段非常困难。为了追踪设计缺陷而对波形进行目视检查总是一项乏味的任务。现在,我们花在验证上的时间超过了我们花在设计上的时间,这几乎占了整个开发工作的70%。
如何尽早尽快发现bug?
下面的topic会为目标提供见解:
- 功能验证需求
- 功能验证技术
- 功能验证路径(approached)
- 功能验证方法论(methodologies)
2.Functional verification requirements
要针对DUT特定的验证需求开发有效的健壮的验证环境。
- Verify all the features/usecases & find all the bugs
- Re-usability
- Progress Measurement
- Automation
- Easy to write and maintain
自动化(Automation)是提高用例执行效率,增强从自检机制到功能覆盖反标结果可观察、分析性。**验证指标(功能点)**有助于跟踪和测量验证完整性的进程。帮助聚焦功能场景中的corner cases。在可执行的验证计划中,包含对于每个特定的待测功能点分配的优先级和权重。我们可以将要测试的特性映射到规范文档中。甚至覆盖结果也可以自动回注到验证计划,显示进展。
复用性:验证环境中的”factory“和“configuration”使集成、测试人员一起工作。
模块化:构建验证组件、环境中提供的思维。它有助于更好地管理基于oop的类的工作产品——从父类扩展而来的子类等等。SystemVerilog支持的继承和多态性促进了这类模块化特性。编码指南是有效验证环境的另一个重要参数。在众多其他好处中,它有助于以一致的方式维护代码&还有助于轻松调试。
functional verification technologies
工业上,2种技术:Simulation Bases Verification 和 Formal Verification(形式验证)进行功能验证。在激励驱动验证中,设计激励是把动态测试向量输入,输出拿来与期望值(golden values)比较。形式验证中,验证人员从理论正确的输出行为入手,让形式验证工具进行验证;同时,验证人员无需注意输入的激励。这种方式称为属性检查(Formal Property Checking)。等效性检查中,在EDA工具驱动下,把两不同设计阶段输出(如:RTL design & 综合后的门级网表;扫描链插入前的网表 & 扫描链插入后的网表)的功能等效性进行比较。
测试向量在概念上可以看作是验证输入空间中的一个点。在这个观点下,基于仿真的验证可以看作是通过输入空间采样的验证;除非对所有点进行采样,否则存在错误逃避验证的可能性。与在point level工作相反,形式验证工作在property level。给定一个属性,形式验证会彻底搜索所有可能的失败输入和状态条件。如果从输出的角度来看,基于仿真验证每次检查一个输出点;形式验证一次检查一组输出点(一组输出点组成一个属性)。
4.Functional Verification Approaches
在复杂的SoC设计流程中,功能验证是非常重要的;功能bug将无法在后续的实现阶段检测到,只有在一个芯片集成到目标系统后才会暴露,导致昂贵的设计和芯片迭代。为了应对这一挑战,一些学术和工业调查实验室一直在进行功能验证的不同方法的研究。下面列出了五种基于动态向量的方法,缺一不可。
- Directed Verification
- Constrained Random Verification
- Coverage Driven Verification
- Assertion Based Verification
- Emulation Based Verification
定向测试是一种传统的方法,它使用手工创建的基于要测试特性的测试用例来在功能上验证设计。定向测试方法可能适用于较小的设计,但随着SoC/IP的规模和功能的不断增长,它可能需要数千个测试案例,这种方法在完全验证设计时遇到了许多遗漏的功能问题和上市时间挑战。
要克服这一限制并提高验证效率,唯一的方法是减少创建工作测试所需的时间。使用约束-随机刺激生成,场景可以在用户指定的一组规则或约束的控制下以自动方式生成。SystemVerilog提供了大量用于描述复杂验证环境的语言功能,包括受约束随机化的激励产生、面向对象编程、多线程功能、进程间通信和同步,以及功能覆盖。
图3显示了使用受约束随机测试方法的验证周期,即分层测试平台开发,测试更大的设计空间(橙色),测试具体边界场景(Connner case),最后通过编写定向测试用例来解决剩余的问题。
覆盖驱动的验证是服务于整个验证过程的关键。非常重要的一点是,通过指出设计中尚未得到充分验证的区域来识别过程中的漏洞。这有助于通过回答下一步要做什么的关键问题来指导验证工作——例如,要编写哪个新的定向测试,或者如何改变/控制受约束随机测试的参数。
另一个更重要的目的是-作为一个指标,流片前的验证是否足够彻底。覆盖率提供的不仅仅是一个简单的是/否的答案,覆盖率度量中的增量改进有助于评估验证的进展和彻底性,从而导致开发团队有信心完成设计。事实上,覆盖率是如此重要,以至于大多数先进的自动化方法都实现了覆盖率驱动的验证,其中覆盖率度量指导过程的每一步。
覆盖率分为两大类:代码覆盖率和功能覆盖率(图6)。代码覆盖率,以其多种形式(line覆盖率、toggle 覆盖率、expression 覆盖率),是一个典型的自动化过程,它告诉特定RTL设计描述中的所有代码是否在特定的模拟运行(或一组运行)期间得到了执行。由功能覆盖模型驱动的功能覆盖有助于指出设计中覆盖/未覆盖的功能点。它可以进一步分为point coverage, transistion coverage and Cross coverage。
断言可以增强任何验证环境的功能性和生产力。断言是简单的术语——设计意图的声明。除此之外,断言在验证周期的许多不同阶段都是有帮助的,例如协议检查器、断言覆盖和相同的断言集可以在模拟过程中使用。
在验证过程中,工程师通常会使用各种工具。他们使用逻辑仿真器进行块级验证,传统上以每秒10-1000个时钟周期进行仿真。然而,逻辑仿真器的性能随着设计规模的增加而急剧下降,使得它们实际上不可能用于系统级集成测试。仿真速度也受到运行设计所需的时钟周期数量的限制;例如,一个完整的视频帧在一个中等大小的设计将需要很多很多时钟周期,因此在单纯仿真中运行很长时间。
仿真器的目标就是填补这一空白。通过在仿真器中模拟实际硬件行为,它可以以每秒几百万个时钟周期的速度运行。在这种方法中,仿真器中的RTL设计与运行在工作站上的Testbench交互,如图6所示。
5.Functional Verification Methodologies
任何一种方法学都会引导我们“如何做”事情。类似地,高级功能验证方法帮助验证提供了一个框架,如果正确使用并建议结果可重用验证组件(UVC/OVC/VIP),通过配置支持更好的可控性,分层测试平台框架和性能改进。