覆盖率烹饪书翻译2010-2013、主要在UART部分
覆盖率烹饪书 |
链接:https://pan.baidu.com/s/1mJIEhn3JPMZ0vXpH2fvi8Q
提取码:qtb3
白
覆盖率... 4
介绍... 5
覆盖率烹饪书... 5
覆盖率指标与流程(理论)... 6
1 覆盖率是什么... 6
1.1 可观察性和可控性... 6
1.2 总结... 7
2 覆盖率类型... 7
2.1 覆盖率分类... 7
2.2 覆盖率空间分类... 8
2.3 覆盖率度量... 8
3 代码覆盖率... 8
3.1 代码覆盖率指标的类型... 9
3.2 典型的代码覆盖率流程... 10
4 功能覆盖率... 11
4.1 功能覆盖率指标的类型... 11
4.2 典型功能覆盖率流程... 13
5 规格书到测试计划... 14
5.1 测试计划创建方法... 14
5.2 在自下而上和自上而下的方法之间选择... 15
5.3 自下而上的例子... 15
5.4 自上而下的例子... 16
5.5 测试计划审查... 18
6 可执行测试计划格式... 18
6.1 创建测试计划的目的... 18
6.2 创建测试计划... 19
6.3 测试计划到功能覆盖率... 21
6.4 功能覆盖示例... 24
覆盖率例子 (实践) 30
1 总线协议覆盖率... 30
1.1 APB3 协议概述... 30
1.2 挖掘协议属性... 31
1.3 实现协议监视器... 32
2 APB3协议测试计划... 32
2.1 APB3协议测试计划... 32
3 APB3协议监视器... 33
3.1 未知信号... 33
3.2 时间关系... 34
3.3 其它属性... 35
3.4 功能覆盖率... 35
3.5 完整示例代码... 36
4 块级覆盖率... 37
4.1 UART总览... 37
4.2 寄存器映射... 37
4.3 额外的接口... 38
4.4 测试平台结构... 38
4.5 设计功能覆盖率模型... 38
5 UART测试计划... 44
5.1 UART测试计划... 44
5.2 UART示例覆盖组... 45
5.3 UART示例源代码... 52
6 数据路径覆盖率... 52
6.1 The BiQuad IIR 滤波器示例... 53
6.2 BiQuad IIR滤波器测试计划... 55
6.3 BiQuad IIR Filter测试计划... 55
6.4 BiQuad IIR滤波器示例 covergroups. 56
7 SoC 覆盖率示例... 59
7.1 Wishbone SoC概述... 60
7.2 功能覆盖模型创建:使用模型图... 61
7.3 功能覆盖模型创建:电子表格... 66
附录... 70
1 要求的写作指南... 70
要求的写作指南... 70
覆盖率
覆盖率烹饪书描述了不同类型的,可以用于跟踪验证进程的覆盖率。描述了如何从规格书创建一个功能覆盖率模型。以及为不同的设计类型提供如何实现功能覆盖率的例子。
覆盖率烹饪书内容
覆盖率-总览页
介绍- 介绍覆盖率烹饪书
覆盖率指标与步骤(理论)
l 覆盖率是什么?- 覆盖率和什么相关,你为什么要用它
l 覆盖率的类型- 不同类型可用覆盖率的解释
- 代码覆盖率 –解释了不同类型代码覆盖率
- 功能覆盖率–描述了各种可选的功能覆盖率形式
l 规格书到验证计划 – 概括了基于规格书创建验证计划的不同方法
- 可执行的验证计划形式 – 描述了可执行验证计划电子数据表的形式
l 功能覆盖率到验证计划 – 解释了如何从验证计划转变为覆盖率模型
- 编程分析 – 如何确保你的功能覆盖率代码能够给予容易解释的结果
覆盖率例子(练习)
l 总线控制覆盖率 – 参数如何使用断言检查总线协议并生成功能覆盖率数据
- APB3协议验证计划 – APB3协议的验证计划
- APB3协议监视器 – 从已实现的APB3协议监视器而来的一系列代码片段
l 块级覆盖率- 一个块级的UART设计,功能覆盖率主要基于配置寄存器
- UART测试计划 – 一个针对UART的测试计划
- UART覆盖组实例 – 阐述了如何实现块级覆盖组的代码片段
l 数据路径覆盖率 – 解释了在数据路径块的设置下覆盖率如何被收集
- BiQuad IIR 滤波器测试计划 – 一个针对BiQuad IIR滤波器的测试计划
- BiQuad IIR 滤波器覆盖组示例 – 阐述BiQuad IIR功能覆盖率模型的代码片段
l SoC覆盖率例子- 解释了基于用例创建SoC功能覆盖率模型的过程
附录
写作指南的要求 – 针对思考和编写要求的指南
请注意,针对覆盖率烹饪书的所有例子,可能有时候无法提供,或者不适合提供源代码
介绍
覆盖率烹饪书
正如谚语所说, "没有被测量的东西或许没有完成"。当试图确定一个设计项目的验证进度,或者试图回答一个重要的问题-“我们完成了吗?”的时候,这是当然正确的。不论你的仿真方法是基于定向测试方法还是受约束的随机验证方法,明确你的验证过程需要回答以下问题:
• 在测试计划中所有的设计特性和需求被验证过了吗?
• 在设计模型中的一些代码行或者结构从未被使用过吗?
覆盖率是我们在仿真期间使用的指标,帮助我们回答这些问题。覆盖率指标是我们验证过程中不可或缺的一部分,它能为更准确的项目进度预测提供可能性,并为优化我们整个验证进度提供一种手段。在成熟阶段,我们能够回答例如以下问题:
• 当我们测试特性X,我们在同一时间测试过功能Y吗?
• 我们的验证进度是否因为一些意外原因而停滞?
• 是否有可以剔除的测试以加速我们的回归流程,并且仍然能够完成我们的覆盖率目标?
你手中的这本书包括了来自于在线覆盖率烹饪书源码的摘录,它正在发展以缓解覆盖率驱动的验证方法学所有方面的问题。例如,覆盖率规划、覆盖率建模、覆盖率实施、覆盖率分析和覆盖率关闭。查看覆盖率烹饪书网址,获取书中的一系列可下载的例子,加入一个感兴趣的工程师社区,学习如何充分利用项目中的覆盖率。
在网上找到我们:https:/ / verificationacademy. com/ cookbook
覆盖率烹饪书作者:
- Gordon Allan
- Gabriel Chidolue
- Thomas Ellis
- Harry Foster
- Michael Horn
- Peet James
- Mark Peryer
覆盖率指标与流程(理论)
1 覆盖率是什么
正如谚语所说, "没有被测量的东西或许没有完成"。当试图确定一个设计项目的验证进度,或者试图回答一个重要的问题-“我们完成了吗?”的时候,这是当然正确的。不论你的仿真方法是基于定向测试方法还是受约束的随机验证方法,明确你的验证过程需要回答以下问题:
- 在测试计划中所有的设计特性和需求被验证过了吗?
- 在设计模型中的一些代码行或者结构从未被使用过吗?
覆盖率是我们在仿真期间使用的度量,帮助我们回答这些问题。然而,一旦覆盖率指标成为我们验证过程中不可或缺的一部分,它能为更准确的项目进度预测提供可能性,并为优化我们整个验证进度提供一种手段。在成熟阶段,我们能够回答例如以下问题:
- 当我们测试特性X,我们在同一时间测试过功能Y吗?
- 我们的验证进度是否因为一些意外原因而停滞?
- 是否有可以剔除的测试以加速我们的回归流程,并且仍然能够完成我们的覆盖率目标?
因此,覆盖率是我们用来测量验证进度和完整性的仿真指标。
1.1 可观察性和可控性
讨论覆盖率的基础是理解可控性和可观测性的概念。非正式的说,可控性是指通过激励各类输入端口,影响或者激活一个内嵌的状态机、结构、特定的代码行或者设计中的行为的能力。请注意,虽然在理论上,一个仿真的testbench在验证期间具有很高的设计模型输入端口可控性,但它在模型内部结构中具有很低的可控性。相比较而言,可观察性指的是观察特定内部有限状态机、结构、或者被激励的代码行影响的能力。因此,一个testbench如果值观测设计模型的外部端口,那它的可观察性通常有限(因为内部信号和结构通常是对testbench间接隐藏的)。
使用仿真testbench方法去明确一个设计错误,以下的条件必须满足:
- testbench必须产生合理的输入激励以激活设计错误。
- testbench必须产生合理的输入激励,将设计错误产生的所有影响传播到输出端口。
- testbench必须包含一个能够检测设计错误的监视器,该设计错误首先被激活,然后传递到一个检测点。
可以设置输入激励激活设计错误的条件,该错误不会传播到一个可观测的输出端口。在这种情况下,上述第一个条件依然适用,第二个条件不存在,如图1所示。
图1. 较差的可观察性和可控性会忽略错误
通常,覆盖率是我们用来测量testbench可控性质量的一种度量。例如,代码覆盖率可以直接地指明由于仿真输入激励的可控性差问题导致未激活的代码行。相似的,功能呢覆盖率可以识别在仿真运行期间由于可控性差导致的从未激活的预期行为。
尽管我们讨论在该部分的讨论聚焦于覆盖率,但需要注意的是,我们通过在设计模型中嵌入断言,缓解可观测性影响,促进低层级的可观测性;在我们的testbench的输出端口上创建监视器,促进高层次的客观测序。
1.2 总结
因此什么是覆盖率?简单的讲,覆盖率是我们用来测量验证进度和完整性的一种度量。覆盖率度量告诉我们设计的什么部分在仿真期间被激活(就是说,testbench的可控性质量)。更重要的是,覆盖率度量指明了我们在仿真期间从未激活的设计部分,允许我们调整输入激励以改进验证。
这里有你可用的不同种类的覆盖率度量,并且如何使用他们的步骤在这本书的例子中被讨论。
2 覆盖率类型
没有一种度量足够完整描述验证过程。例如,我们可能在仿真回归期间获得了100%的代码覆盖率。然而,这不是意味着100%的功能覆盖率得到验证。这个原因是,代码覆盖率并不测量多个设计块内或多个设计块之间行为的并行交互,也不测量发生在一个设计内事件的时序。相似的,我们可能完成100%的功能覆盖率,但只实现90%的代码覆盖率。这可能表明我们的功能覆盖模型中存在对特性忠实的问题(即,覆盖率模型中缺少一个设计的重要行为),或者可能实现了一些最初从未说明的功能(例如,也许规格书和测试计划需要随着后续的步骤中被要求更新)。因此,为了全面了解项目的验证进度,我们通常需要多个度量。
2.1 覆盖率分类
为了开始讨论覆盖率指标的种类,首先来确定覆盖率的各种分类是有帮助的。一般来说,我们可以通过多种方式对覆盖率进行分类,但最常见的两种方式是根据其创建方法(例如,显式与隐式),或来源(例如,规格与实现)。
例如,功能覆盖率是显式覆盖率度量的一个例子,该指标已手动定义并由工程师实施。相比之下,行覆盖和表达式覆盖是隐式覆盖率度量的两个示例,因为它的定义和实现是从RTL表示中自动派生和提取的。
2.2 覆盖率空间分类
与我们刚才描述的两个类别相关联的覆盖率可以组合起来形成覆盖空间,这通常被称为覆盖模型[1]。例如,一个显式的规范覆盖空间由工程师手动创建的覆盖度量组成,该规范覆盖空间从设计需求文档或规格书中提取。另一种显式覆盖率是工程师根据设计行为创建的工具,例如RTL模型中与特定FIFO相关的填充或清空事件。类似地,隐式实现覆盖空间由覆盖度量组成,覆盖度量由工具(如模拟器)自动提取,并从设计实现(如RTL模型)派生。
隐式规范覆盖率空间的另一部分由一些使用工具自动提取,并从设计规格书中派生的覆盖率度量组成。这一部分的覆盖率空间目前是学术研究的一个领域,尽管最近出现了一些EDA工具,它们试图通过观察仿真模式对实现(如RTL模型)的影响来自动提取更高级别的覆盖属性。请注意,这些更高级别的功能行为不能仅从实现中自动提取,这就是为什么它们属于与隐式规范覆盖空间相关联的覆盖率度量。
2.3 覆盖率度量
目前,在工业生产中使用的覆盖率指标主要有两种形式,分别是:
• 代码覆盖率指标(隐式覆盖率)
• 功能覆盖率/断言覆盖率指标(显式覆盖率)
[1] A. Piziali, Functional Verification Coverage Measurement and Analysis, Kluwer Academic Publishers, 2004.
3 代码覆盖率
在本节中,我们将介绍各种覆盖率度量,这些度量与设计模型的隐式实现覆盖率空间相关联。通常,这些度量与设计模型的隐式实现覆盖空间相关的。通常,这些指标被称为代码覆盖率或结构覆盖率指标。
优点:
代码覆盖率的起源可以追溯到20世纪60年代,是最早为系统软件测试发明的方法之一[1]。代码覆盖率的优点之一是,它自动描述程序的源代码在测试期间被激活的程度,从而识别源代码中在测试期间未被激活的结构。与功能覆盖不同,代码覆盖的一个关键好处是,创建结构覆盖率模型是一个自动过程。因此,将代码覆盖率集成到现有的仿真流中很容易,并且不需要更改当前的设计或验证方法。
局限:
在我们题为“什么是覆盖率”的部分中,为实现成功的测试,我们讨论了在仿真过程中必须存在的三个重要条件,他们是:
testbench必须产生合理的输入激励以激活设计错误。
testbench必须产生合理的输入激励,将设计错误产生的所有影响传播到输出端口。
testbench必须包含一个能够检测设计错误的监视器,该设计错误首先被激活,然后传递到一个检测点。
代码覆盖率是对源代码中在仿真过程中激活的结构的度量。代码覆盖率指标的一个限制是,你可能在回归运行期间实现100%的代码覆盖率,这意味着你的testbench提供了激活RTL源代码中所有结构的激励,但你的设计中仍然存在缺陷。例如,输入激励可能激活了一行包含错误的代码,但testbench没有生成额外所需的刺激,而这些激励将bug的影响传播到testbench中可以检测到的某个点。事实上,研究人员已经研究了这个问题,并发现如果testbench实现了90%的代码覆盖率,那么在模拟运行期间,只有54%的代码被覆盖[2]。这意味着一个bug可能存在于一行被标记为已覆盖的代码上,但由于没有足够的输入激励将bug传播到一个可观察点,该bug从未被检测到。
代码覆盖范围的另一个限制是,它没有提供关于规范书中定义的功能实际被测试的确切指示。例如,你可能会遇到这样一种情况:你实现了100%的代码覆盖率,然后假设您完成了。然而,规范书中定义的功能可能从未经过测试,甚至这些功能可能从未实现过!代码覆盖率指标不会帮助您发现这些情况。
即使有这些限制,代码覆盖的自动方面使它成为testbench上识别输入刺激缺陷的相对简单的方法。在你开始推进高级验证步骤性能时,它是覆盖率指标的最佳首选。
3.1 代码覆盖率指标的类型
3.1.1 翻转覆盖率
翻转覆盖率是一种代码覆盖率指标,用于测量寄存器或导线的每一位翻转其值的次数。尽管这是一个相对基本的指标,但许多项目都有一个测试要求,即所有端口和寄存器至少必须经历过0到1和1到0的转换。
总的来说,如果不仔细关注,检查一个翻转覆盖率分析报告可能会让人不知所措,也没有什么价值。例如,翻转覆盖通常用于IP块之间的基本连接检查。此外,了解许多控制结构(如独热码选择总线)已完全执行也是有用的。
3.1.2 行覆盖率
行覆盖率是一种代码覆盖率指标,我们用来确定在仿真期间执行了源代码的哪些行。行覆盖率度量报告将有一个与每行源代码关联的计数,指示该行已执行的总次数。行执行的计数值不仅可用于识别从未执行过的源代码行,而且在工程师认为需要最低行执行阈值以实现充分测试时也很有用。
行覆盖率分析通常表示一个罕见的情形被要求,以激活由于缺少输入刺激而导致的代码行未被覆盖。或者,行覆盖率分析可能会发现,源代码的数据和控制流阻止了它,这要么是因为代码中存在错误,要么是因为在某些IP配置下目前不需要死代码。对于未使用或死代码,你可以选择在覆盖率记录和报告步骤中排除或过滤此代码,这允许您只关注相关代码。
3.1.3 语句覆盖率
语句覆盖率是一种代码覆盖率指标,我们使用它来识别源代码中的哪些语句在仿真过程中被执行了。一般来说,大多数工程师发现,语句覆盖率分析比行覆盖率更有用,因为一条语句通常跨越多行源代码,或者一行源代码上可能出现多条语句。
用于语句覆盖率分析的度量报告将有一个与每行源代码关联的计数,该计数指示语句执行的总次数。该语句执行计数不仅可用于识别从未执行过的源代码行,而且在工程师认为需要达到最低语句执行阈值以实现充分测试时也很有用。
3.1.4 块覆盖率
块覆盖率是语句覆盖率度量的一个变体,用于标识代码块是否已被执行。块被定义为条件语句之间或过程定义内的一组语句,关键点是,如果到达该块,将执行该块内的所有行。该指标用于避免肆无忌惮的工程师通过简单地向代码中添加更多的语句来实现更高的语句覆盖率。
3.1.5 分支覆盖率
分支覆盖率(也称为决策覆盖率)是一种代码覆盖率度量,它报告在控制结构(例如if、case、while、repeat、forever、for和loop语句)中测试的布尔表达式的计算结果是否被同时计算为true和false。整个布尔表达式被视为一个true或false的断言,无论它是否包含逻辑and或逻辑or运算符。
3.1.6 表达式覆盖率
表达式覆盖率(有时称为条件覆盖率)是一种代码覆盖率度量,用于确定每个条件的计算结果是否同时为true和false。条件是不包含逻辑运算符的布尔操作数。因此,表达式覆盖率可以独立地度量布尔条件。
3.1.7 聚焦表达式覆盖率
聚焦表达式覆盖率(FEC),也被称为修改条件/决策覆盖(MC/DC),是DO-178B安全关键软件认证标准以及DO-254正式机载电子硬件认证标准经常使用的代码覆盖率指标。这一指标比条件和决策覆盖率更强。DO-178B对MC/DC的正式定义如下:
程序中的每个入口和出口点都至少被调用过一次,决策中的每个条件都至少产生过一次所有可能的结果,程序中的每个决策都至少产生过一次所有可能的结果,并且决策中的每个条件都被证明会独立地影响决策结果。一个条件被证明是独立地影响决策结果,是通过它只改变该条件,同时保持所有其他可能的条件不变[3]。
值得一提的是,完全封闭式的聚焦表达式覆盖率非同小可。
3.1.8 有限状态机覆盖率
今天的代码覆盖率工具能够识别RTL源代码中的有限状态机。因此,这使得自动提取有限状态机代码覆盖率指标来度量条件成为可能。例如,状态机的每个状态进入的次数,状态机从一个状态转换到每个相邻状态的次数,甚至是顺序arc覆盖率,以识别状态访问转换。
3.2 典型的代码覆盖率流程
收集和分析代码覆盖率指标的目的是识别当前验证环境尚未执行的部分源代码。从项目的角度来看,通常最好等到RTL的实现接近完成,然后才开始认真收集和分析代码覆盖率结果。否则,您可能会浪费大量的周期时间,试图从不断变化的RTL代码中理解移动的目标。话虽如此,我们建议您至少在项目周期的早期(即在认真收集覆盖指标之前)运行一些捕获覆盖指标的仿真,以解决覆盖流程中的任何潜在问题。
从高层次的角度来看,代码覆盖流程通常涉及三个主要步骤,包括:
- 检测RTL代码以收集覆盖率范围
- 运行仿真以捕获和记录覆盖率指标
- 报告并分析覆盖率结果
分析步骤的一部分是识别覆盖盲区,并确定覆盖盲区是否由以下三种情况之一造成:
- 缺少激活未覆盖代码所需的输入激励
- 设计(或testbench)中的一个缺陷,它阻止输入激励激活未覆盖的代码
- 某些IP配置未使用的代码或正常运行条件下预期无法访问的相关代码
第一个条件要求你要么编写额外的定向激励,要么调整随机约束,以生成针对未覆盖代码的所需输入激励。第二个条件显然要求工程师修复阻止执行未覆盖代码的错误。第三个条件可以通过设置覆盖率工具在覆盖率记录和报告步骤中排除未使用的或不可达的代码来解决。正规的工具可以用来自动识别不可到达的代码,然后自动生成排除文件。
[1] J. Miller, C. Maloney, "Systematic mistake analysis of digital computer programs." Communications of the ACM 6(2): 58-63, February 1963.
[2] F. Fallah, S. Devadas, K. Keutzer: "OCCOM: Efficient Computation of Observability-Based Code Coverage Metrics for Functional Verification." Proceedings of the Design Automation Conference, 1998: 152-157
[3] DO-178B, "Software Considerations in Airborne Systems and Equipment Certification", RCTA, December 1992, pp.31, 74.
[4] M. Stuart, D. Dempster: Verification Methodology Manual for Code Coverage in HDL Designs - TransEDA, August 2000
4 功能覆盖率
功能验证的目的是确定我们规范中定义的设计要求是否按预期运行。但是,您如何知道所有指定的功能是否都实际实现了呢?此外,我们如何知道是否所有指定的功能都经过了真正的测试?代码覆盖率指标无法帮助我们回答这些问题。
在本节中,我们将介绍一种称为功能覆盖率的显式覆盖率指标,它可以与设计规范书或实现覆盖率空间相关联。测量功能覆盖率的目的是测量与设计功能要求相关的验证进度。也就是说,功能覆盖帮助我们回答这个问题:是否所有指定的功能需求都已实现,然后在仿真过程中执行?关于如何创建功能覆盖模型的详细信息将在功能覆盖率测试计划一章中单独讨论。
优点:
功能覆盖的起源可以追溯到20世纪90年代,当时出现了受约束的随机仿真。显然,受约束的随机激励生成的价值主张之一是,仿真环境可以自动生成数千个测试,这些测试通常需要大量的手动工作来创建定向测试。然而,受约束的随机激励生成的一个问题是,如果没有在仿真运行后冗长乏味地检查波形的努力,你永远无法确切知道测试了哪些功能。因此,功能覆盖率被发明为一种测量方法,以帮助准确确定仿真回归测试的功能,而无需对波形进行目视检查。
如今,功能覆盖的采用不仅限于受约束的随机仿真环境。事实上,功能覆盖率提供了一种在仿真期间执行需求跟踪的自动方法,这通常是DO-254合规性检查所需的关键步骤。例如,功能覆盖可以通过链接到规范书中定义的特定需求的机制来实现。然后,在仿真运行之后,通过特定的定向或受约束的随机测试检查的需求,可以自动被测量,从未测试过的需求得到自动确定。
局限:
由于功能覆盖率不是一个隐含的覆盖率指标,所以无法自动提取。因此,这需要用户手动创建覆盖率模型。从上层来看,创建功能覆盖模型需要考虑两个不同的步骤:
1. 确定您要测量的功能或设计意图
2. 实现测量功能或设计意图的机制
第一步是通过验证计划来解决,详细内容将在从测试计划到功能覆盖的部分中介绍。
第二步涉及对验证计划步骤中确定的每个覆盖项目的机制进行编码(例如,为验证计划中确定的每个验证目标编码一组SystemVerilog CoverGroup)。在覆盖模型实施阶段,还需要考虑许多细节,例如:确定触发测量的适当点,以及为了测量而定义的可控性(禁用/启用)方面。这些和许多其他细节将在详细的覆盖率示例中解决。
由于功能覆盖率必须手动创建,因此在覆盖率模型中始终存在某些指定功能缺失的风险。
4.1 功能覆盖率指标的类型
任何设计的功能行为,至少从验证环境中的任何接口观察到的,都由数据和时序组件组成。因此,从高上层来看,我们需要考虑两种主要类型的功能覆盖度量:覆盖组和覆盖属性。
4.1.1 覆盖组建模
关于功能覆盖率,设计模型内或接口上状态值的采样可能是最容易理解的。我们将这种形式的功能覆盖称为覆盖组建模。它由总线上观察到的状态值、接口控制信号分组以及寄存器组成。关键是,被测量的值出现在一个单独的显式或隐式采样的时间点上。SystemVerilog covergroups是我们通常用于构建功能数据覆盖模型的机制的一部分,详细信息将在块级设计示例以及相应covergroups实现的示例中讨论。
4.1.2 覆盖属性建模
就功能覆盖而言,在事件序列之间的时序关系可能是最难解释的。然而,确保对这些事件序列进行适当测试是很重要的。我们使用覆盖属性建模来度量事件序列之间的时序关系。覆盖属性最流行的例子可能涉及总线协议上控制信号之间的握手序列。其他示例包括与验证低功耗设计相关的电源状态转换覆盖率。断言和覆盖属性是我们用来构建时序覆盖模型的机制的一部分,它们在总线协议监视器示例中进行了说明。
4.1.3 断言覆盖率
断言覆盖率一词在当今行业中有很多含义。例如,有些人将断言覆盖率定义为断言数与RTL代码行数的比率。然而,断言密度通常是一个用于此度量的更准确术语。在我们的讨论中,我们使用术语断言覆盖率来描述使用断言的覆盖率属性的实现。
4.1.4 覆盖组和覆盖属性的不同之处
为了帮助说明使用覆盖组和覆盖属性建模的覆盖之间的区别,让我们看一个简单非流水线的总线示例,如图1所示。
图1. 简单非并行的总线接口
非流水线总线协议的一个写和读总线序列如图2所示。
图2. 简单非流水线总线协议的写入和读取周期
为了验证我们的总线示例,测试地址总线的写序列和读序列的边界条件(即addr中某些点位包含全零和全一)很重要。此外,在回归过程中,我们在地址总线上覆盖了足够多的非边界条件,这一点也很重要。我们只感兴趣的是在从机被选中且选通使能激活时(即sel==1'b1&&en==1'b1)对地址总线进行采样。最后,我们希望跟踪这些覆盖项的单独写入和读取事件,以确保我们已经充分测试了这两个操作。
这是使用覆盖组对功能覆盖建模的一个示例(例如SystemVerilog covergroup构建)。此外,我们可以使用相同的数据覆盖率方法来测量读写数据总线。
现在,让我们看看这个例子中的覆盖属性。写入和读取周期都遵循标准顺序。例如,让我们检查一个写周期。在时钟1,由于从机选择(sel)和总线启用(en)信号都被取消断言,我们的总线处于INACTIVE状态。写入序列的第一个时钟称为总线START状态,主机通过断言一条从选择线(sel==1'b1)来启动总线初始化。在START状态期间,主机在总线上放置有效地址和有效数据。数据传输(称为总线ACTIVE状态)实际上发生在主机断言总线启用选通信号(en)时。在我们的例子中,它是在时钟3的上升沿检测到的。地址、数据和控制信号在整个ACTIVE状态下都保持有效。
当ACTIVE状态完成时,总线使能选通信号被总线主机取消断言,从而完成当前的单次写入操作。如果主设备已完成将所有数据传输至从设备(即,不再有写入操作),则主设备将取消断言从设备选择信号(sel)。否则,从机选择信号保持断言状态,总线返回到总线START状态以启动新的写入操作。多个背对背写入操作(不返回总线INACTIVE状态)称为突发写入。
从时序覆盖的角度来看,可以编写一组断言,以确保对总线上的状态序列的正确。例如,图3显示了唯一合法的总线状态转换。此外,测试单个写入和读取周期以及写入操作中的突发读取非常重要。事实上,我们可能想要测量各种突发写入和读取周期。
图3. 合法的非流水线总线状态序列
通过组合覆盖组和覆盖属性两个方面,我们能够实现更高忠实原设计的覆盖模型,从而更准确地测量设计的关键特征。
APB3总线协议监视器示例中介绍了如何对时间覆盖进行编码的详细信息。
4.2 典型功能覆盖率流程
在许多方面,典型的功能覆盖率流程与典型的代码覆盖率流程非常相似。收集和分析功能覆盖率指标的目的是从规范书中识别当前验证环境和在其上运行的测试用例尚未执行的特性和需求。从项目的角度来看,通常最好等到与覆盖率相关的测试用例的实现接近完成,然后才开始认真地收集和分析功能覆盖结果。否则,您可能会浪费大量的周期去试图从不断变化的激励中理解移动的目标。话虽如此,我们建议您至少在项目周期的早期(即,在认真收集覆盖指标之前)运行一些捕获覆盖率指标的仿真,以解决覆盖流程中的任何潜在问题。
从高层次的角度来看,功能覆盖率流程通常参与了四个主要步骤,包括:
- 创建功能覆盖模型Create a functional coverage model
- 如果使用断言,则测试RTL模型收集覆盖率
- 运行仿真以捕获和记录覆盖率指标
- 报告并分析覆盖结果
分析步骤的一部分是识别覆盖盲区,并确定覆盖盲区是否由以下三种情况之一造成:
- 缺少激活未覆盖功能所需的输入激励
- 设计(或testbench)中的一个缺陷,阻止输入激励激活未覆盖的功能
- 某些IP配置未使用的功能,或在正常运行条件下预期无法实现的相关功能
第一个条件要求您要么编写额外的定向测试,要么调整随机约束,以生成针对未覆盖功能的所需输入激励。第二个条件显然要求工程师修复阻止未覆盖功能运行的缺陷。第三种情况可以通过设置覆盖工具在覆盖记录和报告步骤中排除未使用或无法访问的功能来解决。
5 规格书到测试计划
5.1 测试计划创建方法
创建覆盖率模型电子表格或测试计划的目标是捕获关于功能覆盖率的设计意图和行为的子集。这是一个耗时的手动过程,需要梳理各种设计规范文件,并一次提取一个必要的需求。最好由一个由架构师、设计师、固件和验证工程师组成的跨职能团队来完成,以获得多个观点和不同的输入。如果没有跨职能部分,设计意图的各类子集很容易被忽略。创建测试计划的最佳方式是召开多次会议,每次会议针对一个特定的设计区域(xyz区块),并持续一段固定的时间(1小时,下周每天早上9点)和一个目标(50个要求)。一般来说,可以采取两种方法:
1.自下而上:逐块或逐接口检查
2.自上而下:遵循芯片的使用模型或数据流。
两种方法
|
自下而上 |
自上而下 |
定义 |
从可用的低级别详细设计和实施规范中提取需求。这种方法更面向设计。 |
从高层架构中提取需求,并使用模型规格书。这种方法以客户/验证/用户为导向。 |
赞成的意见 |
|
|
反对的意见 |
|
|
方法 |
召开一系列会议,每次会议的重点是设计的一个子集,如块或接口,并聚集合适的的规格书和工程人员以提取需求,细化需求,确定优先级,并将其与电子表格中的某个覆盖组、覆盖点或交叉点相联系。 |
与架构师举行一系列认真的会议,首先提出一个单独的高层级用例模型,然后创建一个用例模型文档。使用大量的图表(表格、图等)和最少的文字,深入讨论更多细节。然后把这份文件改成电子表格格式。 |
5.2 在自下而上和自上而下的方法之间选择
通常可以使用自上而下和自下而上的组合。你可以从一个自上而下的流程开始,绘制出主要的流程,自然地产生类别,然后对每个类别进行自下而上的操作。在项目开始时,一旦某种形式的设计规范书准备好,那这样做是明智的。首先提取几百个需求,将它们放入电子表格,然后随着项目的进展添加更多需求。一些团队在提取和细化每个需求时,会立即将每个需求和覆盖元素相链接。其他人则将所有需求输入电子表格,然后进行第二次检查以添加随后的覆盖率链接。没有哪一种方法比另一种好,重要的是在你对特定需求细节记忆犹新的时候完成覆盖率链接。将链接留到项目的后期,意味着您必须重新查看每个需求及其相关文档,这将花费更长的时间。
自下而上 |
自上而下 |
小型设计 |
大型设计 |
良好的设计规格书 |
良好的架构规格书 |
良好的实现规格书 |
使用模型信息访问 |
控制设计 |
数据转移设计 |
通用的(多)应用,被许多客户使用 |
单一应用,专门由一个或几个客户使用 |
5.3 自下而上的例子
下面是带有TX和RX路径的以太网芯片的框图。每条路径都有以太网帧通过的块管道。在各种配置下,其中一些块可以被复用输入或复用输出。此外,还有各种时钟配置,每个模块都有自己的配置设置细节。通过自下而上的方法,我们将检查每个模块的设计规范,并提取出该模块的需求。我们还将检查全局块和时钟多路复用设置,并提取出每个设置的要求。关键是将工作划分为小的、可消化的块或子块,以便在合理的时间内轻松提取详细的需求和行为。
要开始自下而上的方法,你需要做的第一件事是尽可能多地聚集了解设计的人,包括架构师、设计师、验证团队、各种接口的专家等等。接下来,一个团队需要将工作细分为一些逻辑上的、可管理的规模。这可以通过我的头脑风暴图来完成,也被称为思维导图。微软的Visio和类似的软件可以在团队一起集思广益时轻松捕获这些类型的图表。每个主题或子模块可以根据需要被进一步分解,它们都在头脑风暴图中相互关联。下面的头脑风暴图显示了以太网芯片的一个简单示例。对于更复杂的设计,头脑风暴图将有更多的子类别从每个块分支出来,将需求提取工作划分为可管理的数量。头脑风暴图中的每个分支可能最终成为以太网测试计划中相应的一个类别或子类别,或者如果很大,可能是它自己的分层电子表格。一些思维导图软件可以利用这些头脑风暴图,将信息导出到电子表格中,其中包含每个类别和子类别的章节号。这为您的测试计划提供了一个很好的起点和现成的框架。
头脑风暴图是一个很好的开始。然后可以分解每个分组或分支,并召开测试计划创建会议,以充实该特定主题的需求。在每次会议上,收集所有可用的设计和实现规范,以及该区块或主题的任何行业规范,以便参考。
一旦你有了一个主题,你就可以使用黄色粘滞法[1],给一个团队提供便利贴,他们花20分钟把需求提取到黄色的便利贴上,然后把便利贴都贴在白板上,以便进一步分类。规则和特征被提取到详细的需求中,然后每一个都作为一行输入到一个带有标题的电子表格中,以及一个描述该需求本质的简要描述。请参阅下面关于需求的注意事项部分。
在每个需求中添加某种独特的字母数字需求标签号是一个好主意,尤其是当您有多个级别的需求时。然后可以使用这些标签将更高级别的需求与更低级别的需求联系起来,反之亦然。需求跟踪工具,比如ReqTracer,可以通过自动跟踪所有需求来进一步控制需求标签的命名和帮助。另一个好主意是添加其他有用的信息,这将有助于指导每个需求的进一步工作。这些额外的有用信息可能是需求来自规范中的位置、作者、注释、优先级、估计的工作量、稍后要回答的问题,等等。最后,每个需求都需要链接到一些特定的闭包元素,比如covergroup、coverpoint、cross、assertion、test等等。对每个被细化的需求进行第二次检查,并确定优先级是个好主意。有关推荐格式的描述和示例,请参见测试计划格式页面。
覆盖率烹饪书中的apb监视器、uart和datapath示例使用自下而上的规划方法。
关于编写需求的指导原则可以在“需求编写指南”一文中找到。在开始规划过程之前,核查小组最好先编制一份这样的清单,并将其分为规则(必须遵守)和建议(好主意)。实际上,这是为编写需求定义需求。
[1] The Yellow Sticky Method is described in more detail in the book - Verification Plans: The Five-Day Verification Strategy for Modern Hardware Verification Languages by Peet James, Springer 2003.
5.4 自上而下的例子
自上而下的方法可用于和自下而上相同的通用以太网设计。我们开发并遵循设计如何被用于实际应用的流程,而不是逐块进行。我们遵循芯片的使用模式,或者有时候叫做芯片的“生命中的一天”。电源接通了。先发生什么?然后呢?等等。对于这种以太网芯片,高层次使用模型有以下流程:
- 设置/配置
- 块多路复用器配置
- 时钟多路复用器配置
- 然后配置每个块
- 数据路由
- 意外事件(LOS、错误等)
接下来,拓展这个基本的高级流程,展开更多细节。你可以一行一行地做,或者通过路径或模式来做。例如,可能某些块和时钟组合被命名为模式,因此您可以按模式深入了解更多细节。你也可以遵循一条路径,比如系统到线路,线路到系统。
这种方法的一个常见问题是,即使采用这种以太网流水线的设计,其流程简单,需求也很容易呈指数级爆炸,形成看起来太多的组合。这是很常见的,因此需要将爆炸重新处理为一些逻辑故障,如下图所示:
当你看上图中的两个部分时,左边的指数图看起来像一个巨大的不可关闭的覆盖组,而右边的覆盖组和覆盖点则是每个表格或图表的自然沉降物。因此,你取高层次使用模型流程的每个部分,然后你用任何表格或图表来展开每个部分,这些表格或图表对包含那些指数增长的特定的部分很有用。例如,在设置/配置的上述块muxing部分中,您可以开发一个潜在有用的设置表,并对每个设置进行命名。在其他情况下,Y-树、序列、气泡图或其他一些图表会更有用。通常,最好将高层次的使用模型流程和所有这些图表收集到一个新的使用模型文档中,并用最少的文字混合。
使用最能体现使用模型的每个领域指数性质的表格、图表或图表:
• 表格适用于小空间,如寄存器字段的几位或行为列表。
• 气泡图可以很好地显示任务或项目之间的关系,如电源区域及其设置。
• Y树图有助于显示选择和决策、and和or、优先级。
• 序列图显示了进展、因果、握手
• 始终可以将图表组合在一起,如上面的一组表格,通过线连接
参见WB SOC设计示例,了解这些图表在覆盖率上下文中如何使用的使用模型。
一旦你将你的使用模型分解成一个有用的图表和表格的渐进集合,最好将它们放在一个文档中,以便于查看和传播。有些团队将它们组合成一个大的图表;其他人将图表放在一起,在图之间用描述性的信息幻灯片进行演示。这些图表的其他格式包括文档(作为设计架构或实现规范的一章分割或添加)或作为项目网站的html文件。演示格式是最常见、最有用的。收集文件可以有许多名称,例如:
- UMD: Use model document(使用模型文档)
- DITL: Day in the life document(生命文档中的一天)
- CAD: Coverage Architecture Document(覆盖架构文件)
无论您如何称呼该文档,该文档通常都非常有用,可以将新的团队成员引入到设计中,为他们提供清晰的概述。随着验证项目的进展,团队通常会回到本文档和这些图表,以充实更多细节。
一旦你有了UMD,你的验证团队就可以把它作为编写测试计划的指南。他们可以对其进行梳理,提取出需求,并将其放入测试计划中。他们可以将流程图、曲线图和表格制作成电子表格中的一个部分或子部分,如果很大,也可以将其分解成自己的分层电子表格。关键是要划分类别和子类别,以便每个电子表格行针对单个需求,并且可以有效地链接到某个覆盖元素。另一个关键是在大致相同的级别编写每个需求。气泡图中的每个气泡可能是单个需求,也可能是整个需求的一个子部分。Y树图上的每个选项可能是一个或多个需求。每个表可以是一个覆盖范围组、每行或每列、一个覆盖点。
从UMD中提取需求通常遵循与上述相同的自底向上提取过程。由于UMD及其图表的固有流程,UMD通常使其更容易实现。通过实践,验证团队将开始更容易地可视化覆盖组和覆盖点,只需查看其UMD中的所有图表。就像自下而上的方法将链接和类型添加到覆盖组一样,coverpoint、cross、assertion或test最好在编写需求时完成。
有关如何获取UMD内容和创建测试计划电子表格的更多详细信息,请参见Wishbone SOC示例部分。
5.5 测试计划审查
验证过程有许多重要方面,需要验证小组投入时间和精力。testbench的构建、测试的运行、时间表等,往往优先于覆盖模型测试计划电子表格,其开发被推迟。通常,会创建一个初步的测试计划,但忽略了与实际功能覆盖要素的链接。结果是覆盖率实施不佳,覆盖率结果很低。团队最终在黑暗中验证,让随机生成发生,但不使用覆盖率作为反馈指导验证得出任何结论或关闭验证。他们采用了一种“足够好”的覆盖率方法,而不是基于任何真实的覆盖率指标数据。有一个良好的测试计划,其中包含定义良好的需求,每个需求都与真实的覆盖率元素链接是关键。花时间制定这个测试计划从长远来看会有回报。在编写需求时添加链接是最好的方法。它还确保团队不必重新查看获取灵感的每个需求的所有文档。为了避免这个问题,成熟的验证团队按照良好的文档或代码审查流程实现了一个测试计划审查流程。三阶段流程通常效果良好:
(1)初步审查:尽早制定测试计划,并尽早进行第一次审查。这是一个快速的回顾,以确保测试计划已经创建,有覆盖率链接和类型,并且在正确的道路上。它不需要是完美的,但需要是当时能做到的最好的。它将在项目过程中不断发展。
(2)主要评审:在一个项目中大约三分之二的时间里,真正的评审会发生。测试计划是覆盖模型,它定义了设计行为和意图的一个优先子集。这里的目标是确保优先级和选择的子集是正确的。你不能包罗万象。你不可能核实每件事。团队必须选择他们的子集,并在分配的时间内进行最多的验证和覆盖。这项检查需要一些时间,通常需要2-5天。对测试计划进行了详细审查,确保每一行的要求都是明确的,并通过覆盖率链接得到满足。所有问题都得到了解决,并输入到错误跟踪工具中。通常需要某种形式的需求重组来更新测试计划。它可能需要添加内容以适应缺失的内容或设计更改,但通常必须减少,以便在剩余的计划时间内实际完成。通常会发生优先级调整,一些工作会转移到未来的流程中。审查的目标是发现并修复覆盖率模型测试计划电子表格中的任何重大问题或缺失部分。
(3)最终审查:该审查在项目的最后几周进行,如果其他两次审查都做得很好,则是对该计划有效性的最终确认。所有重大问题都应该被发现并解决。在最终评审中,将添加异常细节,并在测试计划结束前解决所有最终问题。
这个测试计划评审过程通常与一个类似的三步代码评审过程结合在一起,在这个过程中,rtl和testbench代码被评审。
6 可执行测试计划格式
测试计划是一份文档,它捕获了设计的重要特性,以及如何验证这些特性。
6.1 创建测试计划的目的
功能验证被描述为SoC设计中的一个主要挑战,许多人认为验证过程的可见性不足是导致这一挑战的主要因素。
这种可见性的缺乏会影响设计质量、进度可预测性和成本(资源/工具/基础设施)。
验证经理需要回答的典型问题是:我们什么时候完成验证?是否验证了系统的所有关键要求?我们是否充分利用所有验证资源来满足项目进度?
通过制定一个可执行计划,捕获我们验证意图的优先列表,我们能够做到以下几点:
• 更好地组织自己。不可能完全验证设计的所有状态,但我们可以确定所有关键、重要和较好的特性,然后制定计划,确保所有关键和一些重要特性在计划内得到充分验证。如果时间表允许,还可以验证其他功能
• 在验证项目的日常执行过程中,可执行计划可以帮助您了解当前状态。现在可以立即跟踪进度,因为您可以确切地看到相对于您想要验证的内容,您处于什么位置。您可以根据里程碑、功能的优先级,甚至资源来可视化这个进度
• 在项目执行过程中,帮助管理功能覆盖率关闭。验证工程师可以将他们的覆盖率关闭工作集中在已被确定为漏洞的关键特性上,然后是重要特性,然后是“较好的”特性
6.2 创建测试计划
在许多情况下,功能将在仿真中验证,并使用代码覆盖率或功能覆盖率记录为已验证。测试计划还可以包括有关实验室验证和固件/硬件集成测试的信息。对于包含代码覆盖率和功能覆盖率的测试计划,测试计划和仿真之间的连接可以自动化。要使测试计划可执行,必须遵循特定的文档格式。Questa的验证管理解决方案使用的格式如下所述。
6.2.1 捕获测试计划
灵活性是将测试计划连接到仿真器的关键。在Questa验证管理的案例中,几种不同的源文件格式是有效的。唯一的要求是源文档必须能够导出为XML文档。例如,Microsoft Word、Microsoft Excel、OpenOffice Writer、OpenOffice Calc和Adobe FrameMaker都可以轻松输出XML文档,这些文档可以进行处理并使其可执行。事实上,在Word和Excel中分别捕获测试计划的一部分是完全可以接受的。然后,这些不同的部分可以组合在一起,正如下面重用现有测试计划部分所述。
在不同的输入选项中,电子表格是最常用的,并且非常适合测试计划中捕获的数据类型。电子表格格式为可视化验证意图提供了一种简洁明了的方法。本文的其余部分将描述电子表格中所需的信息,以及如何灵活地添加额外的信息,以便在整个测试计划的生命周期中使用。
6.2.2 测试计划的内容
将测试需求捕获到计划中是一个过程。这个过程在规范书到测试计划一文中有定义。该过程包括对规范书的严格分析、架构、设计和验证团队之间的协作,以及确保不遗漏任何内容的评审。这个过程中产生的所有需求都需要在测试计划中使用一些必需的结构进行捕获。所需的结构允许测试计划成为可执行的,并成为验证周期的一部分。
6.2.3 所需的计划结构
Questa的验证管理解决方案需要为每个捕获的需求提供四条不同的信息。它们是章节、标题、链接和类型。此外,其他信息是开箱即用的。每个需求的附加信息包括描述、权重和目标。虽然这些附加字段不是必需的,但它们大部分时间都在使用。Questa的验证管理解决方案还具有允许用户定义字段的灵活性。
如果我们查看电子表格格式中通常使用的字段,每个字段都由电子表格中的一列表示。
计划结构
电子表格中的每一行对应于测试计划创建过程中捕获的需求。在Questa的验证管理解决方案中,每一列都有特定的含义。
6.2.4 章节(Section)和标题(Title)
章节和标题列协同工作,在测试计划中创建命名和层次结构。
(章节)章节列通常是一个数字,用于在测试计划中创建层次结构,并将相关的测试计划项以父/子关系组合在一起。在电子表格中,用户负责输入这些信息。通常,您将以数字“1”开始对节进行编号,然后按顺序继续。然后,该部分下的一个子部分将被编号为“1.1”,以此类推,其中每一个额外的层级将通过添加“.”来表示在分区号之间。
(标题)标题列描述要验证的需求或设计特征的名称。这是将出现在Questa中测试部分的名称。此处选择的名称应有其含义,因为它将通过工具流程可见。当Questa提取测试计划时,它使用章节和标题列中的信息为testplan的每一行创建层次名称和唯一标记。例如,考虑到上面简单的测试计划示例,第1.1节将有一个分层名称/testplan/Parent_1/Child_1。
(描述)描述列允许向电子表格中添加更多详细信息。这可能包括对其他文件的引用,以允许工程师收集更多信息,也可能是对需求存在原因的简单解释。任何文本都可以在此列中引起注意。它在技术上是可选的,但在实践中,测试计划中需注意的需求应该在描述列中有一个条目。
(链接和类型)链接和类型列用于明确指出和需求链接的代码或功能覆盖率项。一个需求可以链接到多个不同的覆盖率指标,包括不同类型的指标。Questa支持链接到CoverGroup、Coverpoints、Cross、Assertions、Cover指令、定向测试和代码覆盖度量类型。这些列还允许像重用现有测试计划一节中描述的那样,导入其他测试计划。
(链接)在该列中,您可以指定在覆盖率数据库中链接到相应测试计划项的实际覆盖率对象的名称。这可能包括一个特定的covergroup实例、一个assertion等。
(类型)在这个列中,您指定了链接列中指定的覆盖率对象的类型。
链接和类型列信息一起用于高效地在覆盖率数据库中找到相应的覆盖率对象,并在测试计划和指定的覆盖率对象之间创建链接。这些列使测试计划成为可执行的。
(权重)权重列记录一个整数,该整数反映当前测试计划项在其同级中相对于其父测试计划部分的相对重要性。如果未指定,则默认值为1。Questa使用“加权平均”计算算法计算测试计划的覆盖率时,会考虑这些权重。有关Questa如何计算测试计划覆盖率的更多信息,请参阅Questa关于验证管理的文档。
此外,权重列可以通过为需要排除的测试计划节/项目行指定0值来排除测试计划的部分。
(目标)此列指定特定测试计划部分的验证目标。合法值的范围为1到100,如果未指定,默认值为100。Questa使用此信息确定测试计划部分/部件被视为涵盖的点。它不会改变覆盖率的计算方式。
6.2.5 使用Questa理解其它列
覆盖率测试计划中还可以使用其他特殊用途的列。这些列都是可选的,但是当它们出现时,Questa会利用它们的内容。
(路径)链接到covergroup的特定实例时,存在两个选项。可选地,可以将覆盖组的完整分层路径添加到链接列中。如果在该设计层次结构的级别上只访问一个coverge项,那么这种方法非常有效。但是,如果多个覆盖项被链接到同一层次的设计结构中,则“路径”列允许指定设计路径,该路径将被添加到“链接”列中的条目之前,以创建完全限定的引用。
(未实现的)随着测试计划的定义,在testbench或设计中还不存在相应的覆盖项的情况,捕获需求是很常见的。为了处理这种情况,可以通过在未实现的列中添加一个值“是”或一个大于零的数字,将一个需求设置为未实现。这将导致测试计划覆盖率计算准确地反映存在的需求,该需求的覆盖率为零,而该需求尚未覆盖。默认情况下,除非指定了此列,否则假定实现了需求的覆盖范围。
(用户定义的列)为了确保用户能够灵活地记录与需求相关的其他重要信息,Questa的验证管理解决方案还允许创建用户定义的列。这允许对任何需要跟踪的内容进行规范。它还可以让您更好地了解验证过程。通常添加的一些列包括哪个工程师负责测试需求,以及需求或设计特征的优先级。
这些新增的列有助于回答以下问题:
• 我的高优先级测试计划项目进展如何?
• 在实现当前项目时间表方面,我在哪里?
• 我的资源状况如何?
系统级功能覆盖示例中使用的电子表格添加了所有者和优先级用户定义列。
6.2.6 重用存在的测试计划
通常,能够在其他上下文中使用现有的测试计划是很有用的。以下几种常见情况下,这会变得有用:
- 测试计划是在块级开发的,需要纳入芯片或系统级测试计划。
- 测试计划随IP或验证IP一起交付。例如,特定于协议的验证IP应包含完整的协议测试计划,以确保协议得到完全验证。
- 将自动生成的测试计划纳入我们的子系统或SoC级计划。例如,对于电源感知仿真,仿真器应该能够创建测试计划,以确保电源场景完全可用。
- 将不同编辑工具捕获的测试计划合并到一个主测试计划中。
在这些情况下,现有的测试计划可以分层导入到正在创建的顶级测试计划中,从而可以可视化整个验证工作的深度。当创建这样一个测试计划时,Type列将被赋予一个值“XML”,以通知Questa该部分不引用覆盖率对象,而是引用另一个测试计划文档。“链接”列将用于指定包含被导入的测试计划的实际测试计划文件(通过文件的相对路径或完整路径)。
6.3 测试计划到功能覆盖率
到达功能覆盖关闭是一个从设计功能规范书开始的过程,并通过分析确定:
导出功能覆盖模型并不是一个自动过程,它需要对可用规范进行解释,模型的实现需要仔细考虑。
• 需要测试哪些功能
• 在什么条件下需要测试功能
• 驱动和监控设计接口需要什么样的testbench基础设施
• testbench将如何检查功能是否正常工作
导出功能覆盖模型并不是一个自动过程,它需要对可用规范进行解释,模型的实现需要仔细考虑。
6.3.1 过程概要
生成功能率覆盖模型的过程通常是迭代的,随着测试平台的每个部分和刺激的构建,模型会随着时间的推移而建立。每次迭代都从相关的和可用的功能规范文档开始,这些文档被分析,以识别需要在测试平台中通过配置和激励生成的一些组合检查的特性。
一般来说,测试平台有两个方面,一条控制路径用来刺激被测试的设计,使其进入不同的状态,以便检查其特性;还有一个分析面,用来观察设计对激励的反应。应在测试平台中实现自检机制,以确保设计正确运行,这通常被称为记分板。功能覆盖率模型的作用是确保DUT通过的测试检查了所有相关条件下的设计特征。功能覆盖率模型应基于对设计行为的观察,而不是它被要求如何行为,因此应该在分析路径中实现。考虑这一点最简单的方法是,在测试平台上,必须开发运行在其上的激励和记分板来测试设计的所有特性,并使用功能覆盖模型来确保这些测试的所有预期变化都已成功完成。
验证是一个不完整的过程,即使是“简单”的设计,也很难及时验证所有可用的内容。对于大小合理的设计,在可验证的内容和可用于实现、运行和调试测试用例的时间之间存在权衡,这导致基于项目的技术和商业背景进行优先级排序。明智的验证策略是从最高优先级的项目开始,并确定优先级顺序,同时准备随着项目的进展重新确定列表的优先级。功能覆盖模型应随着每个设计特征的测试而发展,功能覆盖模型的每个附加部分应在激励之前就位。
6.3.2 过程指南
(1)功能覆盖模型基于功能需求
测试平台用于测试设计的特征。功能覆盖模型的作用是检查这些不同变体的特征是否正常工作。特征也可以被称为需求,或者在某些情况下被称为故事。
例如,DUT生成带有CRC字段的数据包。CRC基于数据包的内容,比如说有10个变体。测试平台产生刺激,使DUT产生数据包,记分板检查CRC字段,确保DUT正确计算。在这种情况下,功能覆盖率监视器的作用是确保所有10个数据包变体都已通过检验。
(2)选择最合适的实现
在决定如何实现功能覆盖模型时,可以选择如何实现功能覆盖。SystemVerilog语言支持两种主要类型的功能覆盖:
覆盖率类型 |
被实现为 |
用于 |
覆盖组建模 |
SystemVerilog Covergroups |
当获得已知结果时,检查条件和状态的排列 |
覆盖属性建模 |
SystemVerilog Assertions - sequences and properties |
检查是否观察到一组状态转换 |
Covergroup 功能覆盖率依赖于对一个或多个数据字段的值进行采样,以统计这些值出现的不同排列的次数。
Cover Property或基于时序的覆盖率,是基于计算测试期间特定状态和/或条件序列发生的次数。时间覆盖通常用于获得控制路径或协议上的覆盖,其中时间关系可能会发生变化。例如:
• FIFO是否已进入溢出或下溢状态
• 是否观察到特定类型的总线循环完成
开发功能覆盖模型的第一步是决定针对每个关注领域应采取这两种方法中的哪一种。
(3)功能覆盖率应基于观察
试验平台的激励侧应该用于驱动DUT,激励侧不应该用于覆盖率,因为DUT或激励可能无法正常工作,从而导致错误的覆盖率。相反,功能覆盖率应基于在测试平台上DUT输出处观察到的情况。在UVM测试平台中,功能覆盖率将基于分析的事务内容。这对测试平台的设计和分析的事务有影响。
(4)功能覆盖有效性
功能覆盖率数据仅在通过检查时有效。如果您没有使用自动工具来合并来自不同仿真的覆盖率,那么您应该确保仅在测试通过时对覆盖率模型进行采样。
但是,如果您使用验证管理工具从多个仿真中收集覆盖率,则无需这样做,因为失败测试的覆盖率结果不会与其他功能覆盖率数据合并。
(5)将负面检测和正面检查分开收集
如果验证计划要求对某个功能进行正面和负面测试,则分别设计并收集这两种测试的功能覆盖率。
(6)设计用于分析的覆盖模型
一个常见的错误是开发一个全面的功能覆盖模型,但后来才意识到很难理解结果。使用可用的语言结构可以更容易地理解缺失的覆盖范围。换句话说,在创建功能覆盖模型时,值得投入一些时间,以便在以后需要了解结果时节省时间。有关此主题的更多讨论,请参见用于分析的覆盖率设计页面。
(7)确定适当的忠于原设计的级别
需要与设计实现的细节有多接近?可以应用多少抽象?
在简单的情况下,需要检查的值相对较少,创建与设计细节密切相关的覆盖率模型是一个可管理的问题。然而,当存在广泛的值时,需要就在细节级别上做出谨慎的决定。例如,一个设备具有大约20个可能值的配置可以很容易地直接建模,而像32位地址范围这样的东西需要拆分成一组有趣的值或值范围,这需要一些抽象。
(8)使用一致的编码风格
使用一致的编码风格来实现覆盖组和断言代码非常重要,因为这使它们更容易理解和解释。它还使与验证计划和跟踪工具的集成变得更容易。
有关覆盖组编码风格的示例,请参阅SystemVerilog编码指南。请注意,实际使用的样式并不重要,但使用一致的样式很重要。
6.3.3 基于覆盖组的覆盖率注意事项
在设计基于覆盖组的覆盖率时,需要考虑许多基于设计的功能和特性的关键点。
(1)哪个值是重要的?
通过简单地指定由一个覆盖点对一个变量进行采样,可以很容易地以无知的方式收集信息,这将导致自动生成2**n个bins,其中n是变量中的位数。对于窄宽度字段,这可能是可以的,但对于更宽的字段,这不太可能非常有用。在大多数情况下,将有许多重要的值或值范围需要覆盖,这些值或值范围应从规范书中衍生出来,并作为一组bins编码到coverpoint中。
(2)数据变量之间的依赖关系是什么?
在分析一个设计或数据包应该被配置为哪种方式时,不同变量之间是否存在关系?如果确实存在这种关系,则应在covergroup中指定变量之间的cross。
(3)是否有需要检查的边界条件?
是否有特定值或值的组合需要检查,因为它们处于操作极限或设计中的已知拐点?这必然需要一些规范书的“字里行间的阅读”,以及一些设计或实现知识。确定的任何边界条件都应添加到覆盖率模型中,以确保对其进行测试。
(4)是否存在非法条件?
如果存在不应出现的情况,则covergroup可以使用一个术语来捕捉这些情况。该术语对功能覆盖率没有贡献,但它可以帮助检测设计或测试平台错误。
(5)是否有不重要的条件?
即使是最简单的设计也可能有比实际使用更多的配置方式。如果有一种方法可以确定哪些模式最有可能被使用,那么也有可能会有一些已知无用或不太可能被使用的模式,这些模式可以从收集的覆盖率值排列中忽略。这里也可能有一定程度的优先级,某些配置必须进行测试,然后,如果有时间,可以检查优先级较低的配置。
(6)什么时候是采样覆盖率的合适时间?
数据覆盖率收集代码需要对其引用的数据值进行采样。采样点需要:
• 仅在相关检查通过时发生
• 数据值有效时发生
• 数据值稳定时
如果采样基于接收UVM分析事务,那么如果它直接来自监视器,则可能需要有一种方法来区分有效的和无效的分析流量。如果功能覆盖率收集器从记分板接收分析事务,则记分板应在发送分析事务之前确认检查已通过。
(7)是否存在数据覆盖率采样无效的情况?
如果有,则必须将编写的守卫放入功能覆盖实施代码中。
(8)分析事务中需要哪些信息?
对于基于TLM方法学(如OVM或UVM)的测试平台,功能覆盖所需的信息需要来自分析事务。这意味着分析事务必须具有将被采样的所有信息,这很可能会影响事务以及生成事务的监视器或记分板的设计。
6.3.4 总结
在考虑如何测试设计功能以及该功能应该基于covergroup的功能覆盖模型的什么部分时,请记住回答以下问题:
覆盖率评判 |
要收集数据覆盖范围的特征 |
哪个值如此重要? |
确定要命中的重要值。 |
这些值之间的依赖关系是什么? |
确定数据值之间的重要叉积(cross) |
是否存在违法条件? |
确定不应该出现的值或值的组合 |
什么时候取样合适? |
指定一个有效的采样点 |
什么时候数据无效? |
确定数据不应采样的条件 |
(1)时序覆盖率考虑
控制路径和协议依赖于信号之间的时序关系来实现握手和传输。使用时态sequences和properties最容易验证这些类型的关系。功能覆盖率信息可以通过以下几种方式从这些检查中获得:
- 如果一个property被断言且从未失败,但可以显示为已完成,则可以假定该属性中描述的功能已被涵盖
- 如果一个sequence完成,然后该序列中编码的功能行为已被观察到,且可假设功能覆盖率
- 如果一个sequence完成,则可以对覆盖组进行采样,以检查其在什么条件下完成(混合覆盖率)
- 如果一个property断言通过,则可以使用通过声明触发covergroup的采样,以检查在什么情况下通过(混合覆盖)
(2)检查应该是具体的
一个property或sequence应该只检查一个条件,在一个属性或序列中检查多个条件会导致功能覆盖范围中的错误识别。
如果使用一个sequence和/或融合操作符来定义property,然后,为了收集通过属性的每个潜在路径上的特定功能覆盖率,必须将属性展开并实现为特定于每个路径的序列。
(3)混合覆盖
有时可能需要混合使用数据覆盖率和时序覆盖率技术来收集特定类型的功能覆盖。例如,检查协议传输的所有模式是否都已发生,最好的方法是写入一个property或sequence,标识传输何时成功完成,然后根据协议的感兴趣信号字段对覆盖组进行采样,以检查是否出现了所有相关条件。
APB总线协议监视器包含使用混合功能覆盖的示例实现。
6.4 功能覆盖示例
不同的设计风格需要不同的方法来构建功能覆盖模型。以下是一些成熟的示例,说明了一些常见的设计类:
设计类型 |
覆盖组 |
断言 |
功能覆盖率建模策略 |
链接到例子 |
例子压缩包 |
基于设计的控制 |
可能 |
是 |
在这种风格的设计中,不同的信号之间有定时关系,需要检查和观察它们是否工作 |
APB总线协议举例 |
(download source code examples online at [1] ). |
外设风格设计,通过寄存器编程 |
是 |
可能 |
大多数功能覆盖可以从寄存器的内容派生出来,这些寄存器用于控制和监视设备的行为。寄存器接口也可以服务于数据路径。可以在信号接口上使用断言。 |
UART覆盖率的例子 |
(download source code examples online at [1] ). |
DSP数据路径风格设计 |
是 |
否 |
在这类设计中,激励通过设计数据路径泵送数据,并将输出与参考模型进行比较。功能覆盖主要是关于确保算法的“旋钮”已经被充分测试。 |
Biquad 滤波器的例子 |
(download source code examples online at [1] ). |
聚合器/控制器风格,例如内存控制器 |
是 |
是 |
多个端口上抽象激励组合的覆盖,Config寄存器的覆盖,目标DDR规范的特征覆盖率 |
敬请期待 |
|
具有垂直重用VM分析组件的SoC |
是 |
可能 |
在SoC级别,功能覆盖不是用例驱动的,只有一些接口或块级别的覆盖可以重用 |
SoC覆盖率例子 |
不可提供 |
关注covergroups的实现是一项时间上的投资,当您或其他人需要了解缺失的功能覆盖率在哪里时,这种投资会得到回报。
6.4.1 覆盖组标记
在对covergroup编程时使用标签的方式对理解覆盖率结果有很大影响。可以为covergroup分配一个选项。名称字符串,有助于识别覆盖范围与测试平台的哪个特定部分相关。在covergroup中,coverpoints可以被标记,bins可以被命名。使用所有这些技术,在分析过程中更容易理解覆盖率结果。
6.4.2 覆盖组命名
如果一个测试平台中使用了相同covergroup的多个实例,则option.name参数可用于为每个实例分配标识字符串。构造covergroup时,可以将名称字符串作为参数传入。在UVM环境中,可以使用get_full_name()方法传入名称。请参见下面的代码示例。
covergroup还可以使用covergroup以编程方式命名的set_inst_name()内置方法。
6.4.3 coverpoint和bins标签
作为一个例子,考虑下面来自于UART例子的功能覆盖问题。在本例中,UART字格式由线路控制寄存器(Line Control Register, LCR)的内容决定:
LCR Bit |
值 |
描述 |
[1:0] |
2'b00 |
5数据位 |
2'b01 |
6数据位 |
|
2'b10 |
7数据位 |
|
2'b11 |
8数据位 |
|
2 |
1'b0 |
1停止位 |
1'b1 |
2 停止位 |
|
[5:3] |
3'b??0 |
无校验 |
3'b001 |
奇校验 |
|
3'b011 |
偶校验 |
|
3'b101 |
坚持0校验 |
|
3'b111 |
坚持1校验 |
更低的分析潜力
更高的分析潜力
为了检查所有可能的文字格式是否都已传输,我们可以通过为LCR[5:0]创建覆盖点来实现覆盖组,而不指定任何bins。这将创建一组默认bins,每个bins对应于寄存器的每个可能值,如左侧代码示例所示。如果功能覆盖率收集的这些位至少采样一次,则没有问题,但如果没有,则很难确定哪个箱子对应于哪个条件——请参阅Questa 覆盖组浏览器中的“之前”屏幕截图。在这里,不使用标签导致仿真器使用自动bins,这意味着需要将缺少的箱子值转换为二进制,然后映射到寄存器字段以识别缺少的配置。
实现covergroup的更好方法是为每个寄存器字段使用带标签的coverpoint,然后为寄存器真值表中的每个值使用bins语法。当进行仿真时,创建的向量积反映了不同的bins标签,这使得确定哪些功能覆盖条件没有被采样变得更加容易。它还可以更容易地查看是否存在遗漏的总覆盖条件。请参阅Questa 覆盖组GUI中重构的“之后”屏幕截图。
6.4.4 covergroup选项如何影响覆盖率的报告和计算
功能覆盖率信息的分析受覆盖结果报告方式的影响。covergroup有三个选项会影响覆盖率报告,并可能造成相当大的混乱,它们是:
- option.per_instance
- option.get_inst_coverage
- type_option.merge_instances
如果在实现covergroup的代码中未指定这些选项,则默认情况下不会启用这些选项。换句话说,它们被设置为0。这三个选项应在covergroup中明确声明,以确保覆盖率计算和报告一致且符合要求。
(covergroup类型和实例)
当一个covergroup被声明时,它就变成了一种可以在测试平台中多次实例化的类型——例如,在一个设计中,同一类型的接口用于多个端口,因此同一covergroup用于测量协议覆盖率。默认的覆盖率报告方法是将covergroup类型的覆盖率报告为该类型所有covergroup覆盖率的加权平均值。无法分析哪些接口尚未实现。
(per_instance选项)
如果covergroup中option.per_instance设置为1,则covergroup报告将按每个实例进行细分,但报告的总体覆盖率仍然是加权平均值。在引用的示例中,这将使每个端口的覆盖范围都能被检查,可能会导致检测到设计缺陷或激励生成中的缺陷。
(merge_instances 选项)
如果covergroup中的type_option.merge_instances设置为1,则covergroup的所有实例报告的总体覆盖率是所有覆盖率的合并或逻辑or,而不是加权平均值。如果您有相同设计IP的多个实例,并且测试平台的不同部分以不同的方式使用它,那么这可能很有用。使用merge_instances选项的一个结果是,一个covergroup实例达到100%覆盖率,而另一个实例达到0%覆盖率,此后总体覆盖率将报告为100%。
(get_inst_coverage选项)
要做到使能merge_instances选项的情况,option.get_inst_coverage的值设置为1,以启用SystemVerilog的$get_inst_coverage()系统调用返回covergroup实例的覆盖率,从而允许检查所有单个实例的覆盖率。如果merge_instances选项设置为0,则get_inst_coverage变量无效。
6.4.5 总结
per_instance和merge_instances设置之间的交互:
option.per_instance |
type_option.merge_instances |
覆盖率报告行为 |
0 |
0 |
总体覆盖率报告为覆盖组所有实例的覆盖率的加权平均值 |
1 |
0 |
总体覆盖率报告为覆盖组所有实例的覆盖率的加权平均值,并为覆盖组的每个实例进行分解 |
0 |
1 |
覆盖率报告为覆盖组的单个实例的覆盖率的合并 |
1 |
1 |
整体覆盖率报告为单个覆盖率结果的合并,使能get_inst_coverage(),覆盖率报告对覆盖组的每个实例进行了分解 |
merge_instances 和 get_inst_coverage之间的交互
type_option.merge_instances |
option.get_inst_coverage |
由 $get_inst_coverage()获取的数据返回值 |
1 |
0 |
基于类型的覆盖——即合并所有实例的覆盖率 |
1 |
1 |
特定于实例的覆盖率 |
0 |
1|0 |
特定于实例的覆盖率 |
特定于仿真器的运行时选项
所描述的选项是SystemVerilog LRM中定义的covergroup选项,因此可以添加到covergroup代码中。仿真器还添加了命令行选项,允许用户更改报告覆盖率的方式,尽管这些选项往往是全局性的,会影响被仿真测试平台中的所有覆盖组。
覆盖率例子 (实践)
1 总线协议覆盖率
总线协议定义了总线上主设备和从设备之间的数据传输方式。协议规定了当主设备发出请求时,以及当从设备准备好响应该请求时,使用哪些信号来确认。验证总线协议的一种方法是将协议监视器实现为SystemVerilog接口,该接口使用SVA并发断言和covergroup的混合,以检查它观察到的总线通信量是否符合协议,并收集关于总线上发生的传输类型的功能覆盖信息。协议监控器是一种被动验证组件,用于监控协议信号,它可以连接到测试台顶层的外部信号,也可以绑定到设计内部的内部总线信号。总线协议监视器是可重用验证组件的一个很好的例子。
1.1 APB3 协议概述
ARM AMBA APB3协议是一个简单的外围总线协议的示例,可用于说明与实现协议监视器相关的要点,并说明如何使用它来收集功能覆盖信息。
使用APB3协议,一个主设备可以与多个从设备进行接口。主设备为所有从设备通用的地址、写入和写入数据生成一组控制字段。每个从机由一个单独的外围选择线(PSEL)选择,然后由一个通用的PENABLE信号启用。每个从机生成响应信号、就绪、读取数据和状态,这些信号被多路复用地传输回主机。方框图显示了典型的APB3外围模块。
APB3信号之间的时序关系如下图所示。
1.2 挖掘协议属性
开始定义属性的最简单方法是用英语为每个协议规则编写简单明确的描述。一旦定义并达成一致,那么实现断言代码通常是相对简单的。以下概述的属性也总结为测试计划。对于APB协议,我们可以定义以下内容:
1.2.1 未知的信号(X, Z)
如果协议信号处于未定义状态,则在某些情况下会导致问题。检查未知信号状态的属性在调试设计的早期阶段很有用,但在验证的后期阶段不太有用。然而,它们确实说明了功能覆盖率集合的第一种类型——成功且永不失败的属性证明了该属性的功能覆盖率。
对于APB3协议,以下未知信号规则为真:
1. PSEL应始终处于已知状态
2. 如果至少有一条PSEL线处于逻辑1,则以下控制信号也应处于已知状态
• PADDR
• PENABLE
• PWRITE
3. 如果至少有一条PSEL线位于逻辑1,且PWRITE位于逻辑1,则PWDATA应处于已知状态
4. 如果PSEL和PENABLE均为逻辑1,则PREADY应处于已知状态
5. 如果PREADY处于逻辑1,则PSLVERR应处于已知状态
6. 如果PWRITE处于逻辑0,且PREADY处于逻辑1,则PRDATA应处于已知状态
另一种方法是要求所有总线信号必须始终处于已知状态,但这可能并不总是可行的,而定义的属性是协议在所有条件下正常工作的最低要求。
有关示例实现,请参见示例的未知信号属性部分。
1.2.2 时间关系
协议中的信号之间的定时关系可以使用sequences和properties来描述。如果一个被覆盖的sequence完成,或者一个断言和被覆盖的覆盖属性通过,那么可以为相关函数确定功能覆盖率。对于APB3协议,可以定义以下时序关系:
- 一旦在逻辑1处对PREADY进行采样,PENABLE将在下一个时钟边缘处变低
- 当PSEL线进入逻辑1时,以下信号应保持稳定,直到在逻辑1处对PREADY进行采样时循环结束
- PSEL
- PWRITE
- PADDR
- PWDATA (iff PWRITE处于逻辑1)
- 总线传输之间至少应有一个时钟周期,其中PENABLE为逻辑0
- 当PSEL线路连接到逻辑1时,PENABLE应连接到以下时钟边缘上的逻辑1。
有关这些属性的实现,请参见示例页面上的时序关系部分。
1.2.3 其它属性
可能还有其他协议规则,这些规则在本质上不是严格的时序性的。对于APB3协议,以下属性为真:
- 在任何时候,只有一条PSEL线在逻辑1上处于激活状态
有关实现,请参见示例页面的“其他属性”部分。
1.2.4 功能覆盖率
除了检查用于有效传输的协议断言所表示的功能覆盖率之外,我们还需要检查所有可能的传输类型是否已经发生。最好的方法是使用各种总线字段的数据覆盖率来检查每个有效值的传输是否完成。与总线协议功能覆盖相关的字段包括:
1. PSEL - 总线上的所有PSEL线路都被视为处于活动状态——即传输发生在总线上的所有外围设备上
2. PWRITE - 我们已经看到读写发生
3. PSLVERR - 我们已经看到正常和错误响应发生
在这些字段之间创建cross将检查APB3总线上的主设备和每个从设备之间是否发生了所有类型的传输。有关实现,请参见示例页面上的功能覆盖部分。
可以收集的其他功能覆盖类型包括:
1. 外设延迟-检查是否观察到一系列外设延迟
2. 外设地址范围-检查特定地址范围是否已被访问
然而,这些可能是特定于设计的,应该使用单独的监视器进行收集。
1.3 实现协议监视器
一旦定义了这些关系和属性,就需要在SystemVerilog接口中混合使用SVA和covergroup语法来实现它们。这里描述了一个协议监视器示例。
协议监视器的源代码可在此处下载:
(在线下载源代码示例,网址为https://verificationacademy.com/cookbook/code-examples).
2 APB3协议测试计划
在验证计划步骤中,应创建一个测试计划,其中列出了设计的特征、如何对其进行验证以及如何完成测试。APB3协议监视器是一个可重用的验证组件(VIP),在验证任何具有APB3总线接口的设计时都可以重用。下面列出的测试计划将作为此类设计的测试计划的一部分,有效地作为测试计划层次结构中的叶子导入。
2.1 APB3协议测试计划
信号 |
描述 |
覆盖率类型 |
属性 |
未知信号值检查 |
|||
PRESETn |
PRESETn总是未知状态 |
Assertion |
1 |
PSEL |
PSEL 总是未知状态 |
Assertion |
1 |
PADDR |
当PSEL激活,PADDR合法 |
Assertion |
1 |
PWRITE |
当PSEL激活,PWRITE合法 |
Assertion |
1 |
PENABLE |
当PSEL激活,PENABLE合法 |
Assertion |
1 |
PWDATA |
当PWRITE激活,PWDATA合法 |
Assertion |
1 |
PREADY |
当PENABLE激活,PREADY合法 |
Assertion |
1 |
PSLVERR |
当PENABLE激活,PSLVERR合法 |
Assertion |
1 |
PRDATA |
当PREADY激活,PRDATA合法 |
Assertion |
1 |
时间相关性检查 |
|||
PENABLE取消断言 |
一旦PREADY激活,PENABLE取消断言 |
Assertion, Cover directive |
1 |
PSEL到PENABLE |
PSEL和PENABLE之间只有一个时钟延迟 |
Assertion, Cover directive |
1 |
信号稳定性 |
当PSEL激活时,PWRITE、PADDR和PWDATA信号应该稳定到周期结束 |
Assertion, Cover directive |
1 |
其它检查 |
|||
PSEL独立 |
同一时间只有一条PSEL线路是激活的 |
Assertion |
1 |
功能覆盖率 |
|
|
|
APB3 协议 |
随着所有激活PSEL线路都有所有类型的响应,所有类型的APB3协议传输都已发生。 |
Covergroup |
2 |
3 APB3协议监视器
APB3协议监视器是被动的,旨在成为一个可重用的验证组件。因此,它被参数化,以允许与不同的总线宽度一起使用,端口接口上的所有信号都是输入。该监视器已被实现为一个接口,所有信号均被声明为输入引脚,这使得它可能与UVM测试台中的虚拟接口句柄一起使用,从而允许通过编程方式访问covergroup。将信号声明为输入允许它们显式连接到任何一组APB3总线信号,而无需在信号命名中进行精确匹配。
3.1 未知信号
监视器实现并断言上一页用英语定义的未知协议信号条件的属性。由于这些属性在一个时钟周期内有效,因此无需使用cover指令收集显式覆盖率;如果没有断言失败,则隐含这些属性的覆盖率。
在可能的情况下,使用的方法是定义一个通用属性,该属性可以针对不同的信号进行断言。
3.2 时间关系
监视器实现上一页用英语描述的定时关系。功能覆盖策略是假设如果这些断言没有失败,但被视为以覆盖指令完成,那么它们将添加有效的功能覆盖率:
3.3 其它属性
监视器检查在任何时间点逻辑1上只有一条PSEL线是活动的。由于这个属性在每个时钟周期中都被检查,如果没有故障,那么它隐含了功能覆盖率。
3.4 功能覆盖率
为了检查总线上每个外围设备的每个可能协议条件下的传输是否正确完成,我们实现了一系列covergroup,每个外围设备一个covergroup,它收集特定于该外围设备的协议覆盖率。当一个简单序列保持时,对covergroup进行采样。请注意,为提高性能,仅当相关PSEL线为真时,才对每个covergroup进行采样。
3.5 完整示例代码
监视器和测试评台的源代码可在此处下载:
(在线下载源代码示例,网址为https://verificationacademy.com/cookbook/code-examples )
4 块级覆盖率
块级功能验证可以充分利用这样一个事实,即所有块接口都是公开的,并且可以完全自由地单独进行激励。验证过程的预期结果是,该块已经过彻底测试,因此可以在更高的集成级别上完全放心地重复使用。功能覆盖模型是设备的一部分,用于确定设计是否已验证到所需的质量水平。
块级设计示例是UART,它包含寄存器,允许DUT配置为不同的操作模式,还可用于获取状态信息。UART使用包含UVM寄存器模型的UVM块级测试平台进行验证。
4.1 UART总览
通用同步收发器(UART)的功能是通过一对异步串行线发送和接收不同格式的字符。对于异步串行链路,没有共享采样时钟,而是接收通道使用16倍数据速率的时钟对传入串行数据流进行采样。当没有数据传输时,数据线保持高位,数据字符的传输通过将数据线保持低位一个比特周期来传输起始位开始。接收端检测起始位,然后对串行数据流进行采样和解压,串行数据流可能包含5到8位的数据、奇偶校验,然后是一个始终为1的停止位。
UART 串行格式
4.2 寄存器映射
本例中的UART设计基于行业标准16550a UART。它有10个寄存器来控制它的操作,在一个系统中,软件使用这些寄存器来控制设备以及发送和接收字符。发送和接收路径由16字深的FIFO缓冲。
寄存器映射总结如下:
寄存器 |
地址偏移 |
宽度 |
接入 |
描述 |
Receive Buffer(RXD) |
0x0 |
8 |
R |
接收FIFO输出数据 |
Transmit Buffer(TXD) |
0x0 |
8 |
W |
传送FIFO输入数据 |
Interrupt Enable (IER) |
0x4 |
8 |
R/W |
使能UART中断 |
Interrupt Identification (IIR) |
0x8 |
8 |
R |
中断状态 |
FIFO Control (FCR) |
0x8 |
8 |
W |
设置FIFO接收数据阈值 |
Line Control (LCR) |
0xC |
8 |
R/W |
设置UART数据字的格式 |
Modem Control (MCR) |
0x10 |
8 |
R/W |
用于控制调制解调器接口输出 |
Line Status (LSR) |
0x14 |
8 |
R |
发送和接收通道状态 |
Modem Status (MSR) |
0x18 |
8 |
R |
用于监控调制解调器接口输入 |
Divisor 1 |
0x1C |
8 |
R/W |
16bit传送器的LSB |
Divisor 2 |
0x20 |
8 |
R/W |
16bit传送器的MSB |
对于UVM测试平台,UVM寄存器模型将被写入抽象激励,用于配置和控制UART的操作。使用这个寄存器模型的一个好处是,我们可以在功能覆盖率模型中引用它。有关UART功能和详细寄存器映射的更多详细信息,请参阅数据表。
4.3 额外的接口
UART块有许多需要驱动或监控的离散接口。UART示例测试平台使用UVM实现,因此这些接口的驱动和监控将由通用验证组件(UVC)或agent完成。如果测试平台是使用另一种方法学实现的,那么将使用BFM或类似BFM的模型。然而,建模和收集覆盖范围的原则基本相同。
UART具有以下外部接口,需要在测试平台上驱动和监控这些接口。
- APB主机接口 – 需要一个 APB agent
- TX串行线 – 需要一个 passive UART agent
- RX 串行线 – 需要一个 active UART agent
- Modem 接口 – 需要一个简单的并行 I/O agent
- Interrupt 线 – 需要一个 monitor
4.4 测试平台结构
本例中使用的UVM测试平台架构如方框图所示。
UART测试平台结构
UART的功能测试计划大纲已经创建,作为将其特性映射到测试用例和功能覆盖的过程的一部分。
4.5 设计功能覆盖率模型
功能覆盖率模型的目的是,确保使用测试平台仿真的所有功能测试用例,将设计置于所有被认为有趣的条件下进行测试。功能覆盖率模型基于设计的功能,并与测试平台的工作方式密切相关,因为它将依赖于来自测试平台组件的数据,并且将依赖于测试平台事件进行采样。
UART功能覆盖模型的设计将根据设备内的每个关注的区域进行讨论。在每种情况下,首先考虑必要的测试,然后考虑所需的功能覆盖模型,以确保所有条件都已被测试。
功能覆盖率模型每个部分的covergroups的示例实现将分别描述,并在示例UART测试平台中提供。
4.5.1 发送通道
(测试发送通道)
针对每种可能的字格式,通过检查发送通道是否传输正确的串行格式数据来验证发送通道,这需要激励来配置设计,然后通过填充发送缓冲区来发送数据。UART agent将根据设备的配置解释传输的串行流,并在接收到一个字符时发送分析事务。UART agent中的监视器将对串行数据执行低级格式和奇偶校验错误检查,如果检测到错误,则标记错误,因为它可以访问时钟和数据信号。如果UART工作正常,则传输数据路径应无错误,测试平台没有引入错误的范围。
为了检查发送通道是否正常工作,我们可以将接收到字符时被动UART监视器写入的分析事务内容与最初写入UART传输缓冲区的字符进行比较。这意味着记分板连接到UART agent和APB agent。UART传输缓冲区写入必须在记分板的FIFO结构中进行缓冲,以便与UART接收的字符进行比较。
发送通道有两个缓冲状态位(TX empty和TX FIFO empty),它们从线路状态寄存器读回,需要通过激励生成路径进行测试。还有一个TX FIFO空状态中断,将在中断部分讨论。
(发送通道的功能覆盖率设计)
当测试平台检查UART是否正确传输串行数据时,功能覆盖模型的作用是检查每种字格式是否已配置并正常工作。字格式由行控制寄存器(Line Control Register, LCR)的内容决定,因此功能覆盖模型需要在每次传输字符时对LCR值进行采样。LCR寄存器中有6个bit决定字格式,它们是:
LCR Bit Field |
Function |
[1:0] |
选择 5,6,7 or 8 bit 数据 |
2 |
选择1 or 2 停止位 |
[5:3] |
使能奇偶校验和奇偶校验类型 |
我们需要看到这些配置设置的所有可能排列,用于说明我们已经实现了传输信道的功能覆盖率。用于收集此功能覆盖的SystemVerilog covergroup的示例实现在示例UART测试平台中实现。
(发送通道覆盖率总结)
覆盖率标准 |
发送通道覆盖率 |
哪些变量重要? |
LCR[5:0] – 定义了UART串行字格式的所有排列组合 |
这些值之间的依赖关系是什么? |
无依赖 |
它们是非法的条件吗? |
不,所有组合是合法的 |
什么时候采样合适? |
当一个字符已经被传输 |
什么时候数据非法? |
N/A(不可用) |
4.5.2 接收通道
(测试接收通道)
测试平台使用active UART agent将串行数据流驱动到UART中。active UART是一个验证组件,它根据激励事务驱动接收串行数据线,并监控该线的状态,将pin级别的动作转换回事务。接收通道必须能够处理传入串行数据流格式中可能存在的错误,这需要对接收通道进行正检查和负检查,UART agent驱动能够插入位级错误,其监视器能够检测到这些错误。
接收记分板使用的检查机制是将UART agent发送的数据与从UART设备的接收缓冲区读取的数据进行比较。UART代理插入的任何错误都需要被设计视为线路状态寄存器(LSR)中设置的位或通过生成线路状态中断来检测。测试平台需要对接收通道进行的检查包括:
• 正确检测到起始位
• 已正确接收奇偶校验-如果没有,则生成奇偶校验错误
• 至少接收到一个停止位——如果没有,则生成帧错误
• 正确检测到数据溢出情况
• 数据接收标志正常工作
• 正确检测到断路情况
中断一节中考虑了许多接收通道中断条件。
(接收通道的功能覆盖率设计)
接收通道的功能覆盖率模型需要收集无错误条件下的功能覆盖率,然后收集每个可能的错误或特殊条件下的功能覆盖率。接收通道的字格式通过LCR进行配置,因此对于无错误字符格式,可以使用与传输通道相同的covergroup设计,除了当从UART的接收缓冲区读取数据字符时,会对其进行采样。
对于各种错误情况,使用单独的covergroup,这会将线路状态寄存器(LSR,Line Status Register)中的奇偶校验错误、帧错误、溢出错误和中断条件位与LCR中的字格式位交叉。这可以确保所有字格式下都检测到所有可能的错误或特殊情况。
这些covergroup的示例实现在示例UART测试平台中提供。
(接收通道覆盖率总结)
覆盖率标准 |
接收通道覆盖率 |
哪些变量重要? |
LCR[5:0] – 定义了UART串行字格式的所有排列组合 LSR[4:0] – 状态位 Break Interrupt (BI), 帧错误 (FE), 奇偶校验错误 (PE), 超速错误 (OE) and 数据接收 (DR) |
这些值之间的依赖关系是什么? |
对于无错误RX条件DR和所有字格式(For error free RX conditions DR and all word formats) 对于注入错误RX,LCR和LSR位的叉积 |
它们是非法的条件吗? |
不能在没有DR合法时有OE |
什么时候采样合适? |
当RX字符已被传送且DR合法 |
什么时候数据非法? |
N/A |
4.5.3 调制解调接口
(测试调制解调接口)
调制解调器接口是一组4个输入和4个输出信号,用于在两个UART之间实现硬件握手。在一些UART设计中,这些线路与UART状态机具有硬件互锁,以启用/禁用数据的传输和接收,但这种UART设计并非如此。调制解调器的输出是通过写入调制解调器控制寄存器(MCR, Modem Control Register)来驱动的,对调制解调器输入的更改将从调制解调器状态寄存器(MSR)读取回来。
还有一个回环模式也需要检查。在这种模式下,对MCR的写入会被反射回MSR(Modem Status Register)中,外部信号不会改变或导致任何改变。调制解调器记分板会将此功能与正常操作模式分开检查。
测试平台包含一个调制解调器代理,该代理有一个用于调制解调器输入的驱动程序和一个监视器,当任何调制解调器信号(输入或输出)发生变化时,该监视器将事务发送到调制解调器记分板。记分板还从APB代理的监视器接收事务,以便它可以1跟踪UART寄存器访问,这使它能够知道调制解调器输出何时应因写入MCR而发生更改,以及2调制解调器输入更改何时应反映在MSR的读取中。
(调制解调器接口的功能覆盖率设计)
调制解调器记分板检查调制解调器接口是否正常工作,总的来说,这包括调制解调器寄存器和调制解调器信号之间的路径。
对于调制解调器输出,所有可能的输出信号组合都需要在有回环或无回环的情况下进行观察,这意味着当MCR的内容被测试平台写入时可以对其进行采样。所需的功能覆盖包括信号条件的所有排列。
调制解调器输入从MSR读回,有四个信号采样值和四个信号变化值,需要看到它们已在所有可能的状态下读回。回环位影响MSR值是来自调制解调器接口信号还是来自MCR信号,因此这需要成为覆盖率模型的一部分。读取MSR时对调制解调器输入覆盖率模型进行采样,所需要的覆盖率是MSR的所有可能值加上MCR环回位的值的叉乘。
这些覆盖模型的示例实现在示例uart测试平台的uart_modem_coverage_monitor中。
(调制解调器接口覆盖率汇总)
覆盖率标准 |
调制解调器接口覆盖率 |
哪些变量重要? |
MCR[4:0] -控制输出和回环模式 MSR[7:0] -输入状态和改变到输入值 |
这些值之间的依赖关系是什么? |
每个调制解调器信号都是正交的,但是回环模式在MCR位和MSR位之间创建了依赖关系。 对于覆盖率,所有排列都是相关的。 |
它们是非法的条件吗? |
不 |
什么时候采样合适? |
当调制解调器接口上发生更改,或对MCR进行写操作时 由调制解调器记分板决定。 |
什么时候数据非法? |
在回环模式改变后,立即由记分板处理 |
4.5.4 UART中断
(测试UART中断)
测试平台包含一个UART中断线的监视器,一些测试用例具有激励,可以启用各种中断,然后在中断发生时处理中断条件。测试平台内的记分板根据中断源检查中断条件的有效性。UART可在以下情况下产生中断:
- 传输FIFO为空
- 达到接收数据FIFO阈值(1、4、8、14个字符)
- 接收机线路状态——奇偶校验错误、帧错误或中断条件
- 接收器超时-FIFO中至少有一个字符,但在至少4个字符的时间内没有接收通道活动
- 调制解调器状态更改
(UART中断的功能覆盖率设计)
有几个领域需要收集功能覆盖率。第一个问题是检查中断启用和中断源的所有可能组合是否已测试。
中断启用寄存器(IER)是一个四位寄存器,用于启用不同的中断类型,当发生中断时,需要对所有可能的活动状态进行采样,即至少启用一个中断。如果在没有激活启用的情况下发生中断,则这是一种错误情况。
中断识别寄存器(IIR)优先考虑活动中断状态。当中断发生后读取IIR时,需要对该寄存器的值进行采样。需要观察所有IIR值,但在任何时间点可观察到的IIR值取决于中断优先级和IER的内容。因此,IIR状态代码需要与IER值交叉,但在无法发生的情况下进行过滤——例如,除非启用接收状态中断,否则不会发生接收状态中断。
接收FIFO阈值的四个可能值与所有可能的字格式交叉时,需要看到接收机FIFO阈值电平中断发生。当接收FIFO阈值中断发生时,需要对该覆盖组进行采样。
接收线路状态中断有几个潜在的源,当线路状态中断发生时,需要对其功能覆盖范围进行采样。需要采样的数据是奇偶校验错误、帧错误、超限错误或中断条件的线路状态,以及FIFO错误位,这些位需要交叉,但在过滤了一些非法条件的情况下——例如,没有活动线路状态位的线路状态中断会重复错误,或者中断条件会使奇偶校验和帧错误无效。
应检查发送器为空的中断是否存在所有可能的字格式。
调制解调器状态中断可能来自MSR的四个信号变化检测位之一。这些位与所有排列交叉,也与MCR环回位交叉。当调制解调器状态中断发生时,对调制解调器状态中断源covergroup进行采样。
这里可以找到用于捕获UART中断功能覆盖的CoverGroup的示例实现。
- 发送字格式中断、
- 接收字格式中断
- 接收状态字格式中断
- 接收超时字格式中断
- 中断使能IER
- 中断使能源IER、IIR
- 接收数据未使能,不需要监控IIR的状态---接收数据可用中断
- 发送数据未使能,不需要监控IIR的状态---发送保持寄存器为空中断
- 状态线状态未使能,不需要监控IIR的状态---字符超时,接收线状态中断
- 调制解调状态未使能,不需要监控IIR的状态---调制解调状态中断
- 调制解调接口(上一节)
(UART 中断覆盖率总结)
中断处理 |
|
|
覆盖率标准 |
UART中断覆盖率总结 |
|
哪些变量重要? |
IER[3:0] – 使能四个来源的中断 IIR[[3:0] – 指示中断源 |
|
这些值之间的依赖关系是什么? |
中断只在使能后发生 需要观察所有中断源和中断使能的排列组合 |
|
它们是非法的条件吗? |
非法条件是当中断类型未启用时报告的中断源 |
|
什么时候采样合适? |
对于中断启用,当发生中断时 对于中断ID,当发生中断时,从IIR寄存器读取 |
|
什么时候数据非法? |
N/A |
|
接收FIFO阈值中断 |
||
覆盖率标准 |
UART中断覆盖率总结 |
|
哪些变量重要? |
LCR[5:0] – 定义不同的字格式 FC[7:6] – 定义不同的FIFO阈值 |
|
这些值之间的依赖关系是什么? |
LCR和FCR位之间需要交叉,以确保所有可能的排列都发生了FIFO阈值中断。 |
|
它们是非法的条件吗? |
None |
|
什么时候采样合适? |
当RX的FIFO阈值触发后 |
|
什么时候数据非法? |
N/A |
|
接收线状态中断 |
||
覆盖率标准 |
UART中断覆盖率总结 |
|
哪些变量重要? |
LSR[4:1] – 定义不同的RX线状态 |
|
这些值之间的依赖关系是什么? |
无,每个线有不同的来源 |
|
它们是非法的条件吗? |
当终止条件发生,PE和FE非法 |
|
什么时候采样合适? |
当中断线发生,从LSR中读之后 |
|
什么时候数据非法? |
N/A |
|
发送线空中断 |
||
覆盖率标准 |
UART中断覆盖率总结 |
|
哪些变量重要? |
LCR[5:0] -定义UART串行线格式 |
|
这些值之间的依赖关系是什么? |
定义单词格式的所有排列的叉积 |
|
它们是非法的条件吗? |
None |
|
什么时候采样合适? |
当RX空中断发送后,从LSR中读之后 |
|
什么时候数据非法? |
N/A |
|
调制解调状态中断 |
||
覆盖率标准 |
UART中断覆盖率总结 |
|
哪些变量重要? |
MSR[3:0] – 调制解调信号改变位 |
|
这些值之间的依赖关系是什么? |
无,每个信号都是正交的 |
|
它们是非法的条件吗? |
None |
|
什么时候采样合适? |
当调制解调中断发送,在MSR读之后 |
|
什么时候数据非法? |
MSR的标记在读后重置,第二次读将非法 |
4.5.5 波特率除数
(测试波特率除数)
UART串行流以16倍的数据速率采样。UART内部有一个16位除法器,它将APB PCLK向下分割,以生成16倍数据速率时钟。检查数据是否能以不同的数据速率正确接收和传输很重要,但在所有可能的除法器值下检查所有功能将花费太长时间。除法器值越大,数据速率越慢,因此大多数UART功能都是在高数据速率下测试的,以节省模拟时间。
UART有一个数据速率分频器输出–BAUD_O。这可以用不同的速率进行检查,而不是使用专门的检查组件检查UART的其余功能,该组件查看此信号,并使用APB PCLK计算BAUD_O转换之间的间隔。该组件还接收APB总线分析事务,以便确定何时更改除法器值。分隔器的功能覆盖范围可在此组件内收集。
波特率除数的函数覆盖设计
(波特率除数的函数覆盖设计)
波特率除数可以有65536个可能的值,不需要检查它们是否都工作。然而,应该选择一些战略价值观,以确保特定的角落案例被视为有效。具体哪些值是重要的取决于除法器的实现,但我们知道的是,除法器值是通过两个8位寄存器编程的。covergroup在每次BAUD_O转换时采样。
如果我们知道目标应用程序中APB PCLK的频率,我们也可以针对标准波特率的除法器比率,例如每秒1200、2400、4800、9600、14400、19200、38400、57600和115200位。
(波特率除数覆盖率总结)
覆盖率标准 |
接收通道覆盖率 |
哪些变量重要? |
DIV1 和DIV2 寄存器内容,潜在的所有值 |
这些值之间的依赖关系是什么? |
DIV1和DIV2是连接的,否则无关 |
它们是非法的条件吗? |
分频器值不能为0 |
什么时候采样合适? |
在BAUD_O signal的上升沿 |
什么时候数据非法? |
如果分频器寄存器正在编程或刚刚编程,在这种情况下,分频比将与寄存器内容不匹配(这不是错误) |
4.5.6 寄存器接口
(测试寄存器接口)
寄存器接口通过各种测试用例的功能刺激隐式测试。有一个特定的测试用例来检查寄存器重置值是否正确。
(寄存器接口的功能覆盖率设计)
为了检查所有可能的寄存器访问都已发生,使用寄存器地址和读/写位值的交叉。寄存器访问覆盖组在每次寄存器传输结束时采样。只读或只写的寄存器被排除在写入和读取访问的交叉之外。
这种类型的寄存器接口覆盖率通常由寄存器生成器自动生成。
(注册接口覆盖率总结)
覆盖率标准 |
接收通道覆盖率 |
哪些变量重要? |
地址[7:0]是读写位 只关心合法的地址 |
这些值之间的依赖关系是什么? |
需要将有效地址与读/写位交叉以获得寄存器访问空间 |
它们是非法的条件吗? |
MSR和LSR只读,写入非法 |
什么时候采样合适? |
当APB事务完成 |
什么时候数据非法? |
N/A |
5 UART测试计划
作为验证计划过程的一部分,应制定测试计划,列出所有待测试的设计特征,并帮助确定检查所有测试是否已在所有条件下运行所需的功能覆盖类型。测试计划可以是自动跟踪系统的输入,在该系统中,功能覆盖率结果被收集并与计划中的条目进行比较,以允许验证团队测量进度,并帮助确定下一步要做什么。通常,会有一种方法将测试平台中的covergroup和断言与计划文档中的项目联系起来。
编写测试计划是一个迭代过程,这里显示的是UART示例的测试计划的“快照”。
5.1 UART测试计划
部分 |
描述 |
覆盖率类型 |
优先级 |
寄存器 |
|||
复位值 |
所有寄存器复位到对应值 |
测试结果 |
1 |
寄存器访问 |
所有寄存器以所有可能的模式访问 |
覆盖率组、交叉覆盖 |
1 |
位级寄存器访问 |
寄存器所有读写位正确翻转 |
测试结果 |
1 |
APB 协议 |
APB 协议在所有模式下测试过 |
APB 监视器 |
1 |
发送器 |
|||
字符格式 |
所有可能的字符格式被正确发送 |
覆盖率组、交叉覆盖 |
1 |
TX FIFO 空标记 |
当FIFO是空时设置FIFO空标记,正确读回 |
设计断言,覆盖率组 |
1 |
TX 空标记 |
发送空标记正确设置,正确读回 |
设计断言,覆盖率组 |
1 |
接收器 |
|||
字符格式 |
所有可能的字符格式被正确接收 |
覆盖率组、交叉覆盖 |
1 |
数据接收标记 |
当数据可用,数据接收标记被设置,正确读回 |
设计断言,覆盖率组 |
1 |
RX线状态 |
|||
帧错误 |
针对1或2个停止位,帧错误被探测到 |
设计断言,覆盖率组 |
2 |
校验错误 |
所有类型的校验错误被探测到 |
设计断言,覆盖率组 |
1 |
中断指示 |
针对所有类型的字格式,中断条件被探测到 |
覆盖率组、交叉覆盖 |
2 |
超速错误 |
针对所有字符格式,接收超时被探测到 |
覆盖率组、交叉覆盖 |
2 |
FIFO错误 |
针对所有错误/指示类型,FIFO错误条件合法 |
覆盖率组、交叉覆盖 |
2 |
状态 |
任何合理的错误/指示类型结合被探测到 |
覆盖率组、交叉覆盖 |
2 |
调制解调接口 |
|||
调制解调输出 |
调制解调输出值的所有结合被观测到 |
覆盖率组、交叉覆盖 |
3 |
调制解调输入 |
调制解调输入值的所有结合被观测到 |
覆盖率组、交叉覆盖 |
3 |
调制解调输入状态改变信号正常工作 |
设计断言,覆盖率组 |
3 |
|
回环模式 |
调制解调器输出位被路由到正确的调制解调器状态位 |
覆盖率组 |
2 |
中断 |
|||
中断使能 |
中断使能位的所有结合被使用 |
覆盖率组、交叉覆盖 |
1 |
中断ID |
所有合法的中断ID被探测到 |
覆盖率组、交叉覆盖 |
1 |
接收FIFO中断 |
所有可能的字符格式被观测到 |
覆盖率组、交叉覆盖 |
1 |
所有可能的RX FIFO阈值被检查 |
覆盖率组、交叉覆盖 |
2 |
|
接收线状态(RLS)中断 |
为所有可能的错误组合和所有字符格式的指示符生成的中断 |
覆盖率组、交叉覆盖 |
1 |
发送为空中断 |
为所有字符格式产生 |
覆盖率组、交叉覆盖 |
1 |
调制解调状态中断 |
为所有信号改变的结合产生 |
覆盖率组、交叉覆盖 |
3 |
接收超时中断 |
是否检查了最短和最长的字符格式和4个其他格式 |
覆盖率组 |
4 |
波特率 |
|||
分频器的值 |
检查UART操作波特率分频器值的范围 |
覆盖率组 |
1 |
通过波特率分频器输出检查波特率分频器比的选择值 |
覆盖率组 |
2 |
|
代码覆盖率 |
|||
语句覆盖(statement) |
检查已经介绍过的RTL的每个可执行行 |
|
1 |
分支覆盖 |
检查RTL中的每个分支 |
|
1 |
FSM 覆盖率 |
RTL FSMs中的每条弧线都已被取走 |
|
1 |
注意:
1 优先级列表示每个功能的相对重要性。标记为优先级1的项目将首先进行验证,然后是优先级2的项目,最后是优先级4的项目。
2 通过将APB协议监视器插入测试平台,连接到UART上的APB端口,检查APB接口行为,其功能覆盖范围将与其他UART功能覆盖范围合并
3 使用设计师在设计中实现的断言执行了几项检查,这些断言作为设计断言包含在表中
4 代码覆盖率作为一个类别包含在测试计划中,以便对其进行跟踪
5.2 UART示例覆盖组
本页上的covergroup示例是块级功能覆盖示例页上功能覆盖描述的实现。它们说明了如何对covergroup进行编码的不同方面,并在这里进行了描述,以便让您了解高级功能描述如何映射到具体实现。它们的呈现顺序与更高级别页面上描述的顺序相同。
5.2.1 UART发送信道覆盖率
传输信道的功能覆盖组基于UART LCR寄存器的内容。其目的是确定所有可能的文字格式都已传输。每次TX数据记分板确定已传输字符时,都会对covergroup进行采样。covergroup在UVM subscriber组件中实现。
5.2.2 UART接收信道覆盖率
无错误接收和存在错误或特殊情况的接收需要接收通道覆盖。用于无错误接收的covergroup与用于传输信道覆盖的covergroup相同,只是当记分板确定从UART RX缓冲区读取无错误接收字符时,会对其进行采样。对于非无错误覆盖,LSR的相关位与LCR寄存器的字格式位交叉
5.2.3 UART调制解调器接口覆盖率
将MCR寄存器中的位交叉,以检查所有可能的排列是否已编程。MSR寄存器中的位也与自身和MCR中的环回位交叉,以确保观察到所有可能的状态。这两个covergroup都在一个UVM订阅服务器内实现,该订阅服务器接收注册访问事务,并根据地址和读写方向确定要采样的covergroup-请参阅write()方法。
5.2.4 UART中断覆盖率
检查UART中断功能覆盖范围需要多个covergroup。
(中断使能覆盖率)
每次发生中断时,都会对该covergroup进行采样。它检查IER寄存器的状态,对位模式进行解码,以确定哪些中断组合尚未启用。
(中断源覆盖率)
此covergroup检查是否已对所有可能的中断状态条件进行采样。它将IER的内容与IIR交叉,并过滤无法发生的条件。交叉中的ignore_bins确保如果中断被禁用,则该类型的中断ID在交叉中被忽略。。当中断后从IIR寄存器读取时,对其进行采样。
(接收FIFO阈值中断覆盖率)
接收FIFO阈值电平由FCR寄存器的位[7:6]确定。当接收阈值中断发生时,字格式与FCR位交叉,以确保出现所有可能的组合。当中断发生后,从IIR寄存器读取指示FIFO阈值中断时,对其进行采样。
(接收线路状态中断覆盖率)
当线路状态中断发生,然后从LSR寄存器读取时,对该覆盖组进行采样。
关于这个覆盖组的bins,有一些事情需要注意:
- 如果出现中断,则也可能产生帧和奇偶校验错误
- 接收线路状态中断启用也会启用RX超时,该covergroup不会检测到这一点,这就是为什么存在no_ints bin的原因
(调制解调器状态中断覆盖率)
调制解调器状态中断可能是由四个状态位中的一个变为真引起的,此covergroup检查所有四个位是否都处于活动状态,以及在没有任何位处于活动状态但发生调制解调器状态中断时的错误情况。MSR条件与MCR环回位交叉,因为它们可以在正常和环回模式下生成。当调制解调器状态中断后从MSR读取数据时,对该covergroup进行采样。
请注意,由于使用通配符存储单元来检查每个MSR中断源位是否被视为活动真位,而不是所有组合,因此该covergroup的保真度降低。这背后的原因是,每一位都与另一位正交,因此它们之间没有函数关系。
5.2.5 波特率除数覆盖率
波特率检测器每次确定波特率已稳定时,都会对波特率除数寄存器进行采样。选择采样值的依据是,它们代表的值可能会对除法器的实施造成问题。
5.2.6 注册访问覆盖率
此covergroup的目的是检查是否已发生所有有效的寄存器访问。每次有寄存器访问时都会对其进行采样。它为每个有效寄存器地址和读/写位的每个状态命名了bins,这些bin与忽略bin交叉,以确保正确处理只读LSR和MSR寄存器。
5.3 UART示例源代码
UART covergroups、UART RTL和实现多个测试的UVM测试台的源代码可以从这里下载:
(在线下载源代码示例,网址为https://verificationacademy.com/cookbook/code-examples ).
请注意,UART的RTL是示例代码,作为示例的一部分提供,不保证其正确性。绝对不能在真正的设计中使用它。
6 数据路径覆盖率
(什么是数据路径块?)
datapath块接收输入数据流,并实现生成输出数据的转换函数。传递函数的设置可能会改变其特性,也可能是固定的实现。在从输入到输出的路径中,数据不与其他块交互,因此称为数据路径。数据路径块的示例包括自定义DSP功能、调制解调器、编码器和解码器以及纠错硬件。
数据路径块通常使用有意义的数据而不是随机数据进行测试,输出与转换函数的输入相关,因此也有意义。数据路径块的输入很可能是由基于软件(c)的系统模型生成的,在该系统中最初对功能进行了建模,块的输出通常与黄金参考模型的输出进行比较。
在某些情况下,输出数据可能需要进行主观测试。例如,一个视频编码块需要一个视频格式信号作为其输入,并且必须目视检查编码输出,以检查编码结果是否具有可接受的质量。
数据路径设计
数据路径块的功能覆盖范围通常集中在其设置(有时称为“旋钮”)或影响其转换功能的参数上。功能覆盖模型的作用是检查模块是否已使用所有所需的参数设置组合进行了测试。输入数据路径块的数据值也可能与覆盖率有关,因为它可以用来证明输入值的组合已经针对每个有效的参数集进行了处理。
6.1 The BiQuad IIR 滤波器示例
为了说明如何为数据路径块设计功能覆盖模型,将使用一个相对简单的双二次IIR滤波器作为示例。该滤波器接收代表模拟值的数字数据流,并且滤波器中不同抽头的系数值允许处理输入数据以生成输出数据。使用不同的系数值,滤波器可以配置为低通(LP)、高通(HP)或带通(BP)滤波器,具有不同的滚降点。这里不提供计算系数值的数学,但可以使用电子表格进行计算。
BiQuad 滤波器
从理论上讲,双二次滤波器设计可以处理连续或无限范围的可能输入和协效率值,因此验证问题需要限制在实际的范围内。在这种情况下,IIR滤波器将用作频率在50 Hz和20 KHz之间的音频数据的可编程滤波器,并将测试其在频率范围内作为低通、高通和带通滤波器的正确操作,改变系数值以设置转角频率。系数存储在寄存器中,可以使用APB接口编程。输入数据将为扫频正弦波,并检查产生的输出正弦波,以确保已根据滤波器的预期特性达到适当的衰减水平。下图说明了过滤器测试台架构。
BiQuad 测试平台
对于每种滤波器类型,转角频率的滤波器参数将在0-4 KHz范围内以200 Hz的间隔进行测试,然后在4-20 KHz范围内以1 KHz的间隔进行测试——这相当于36组可能的系数值,每一组系数值对特定转角频率有效。
将对输入频率扫描波形进行采样,以确保其涵盖所有感兴趣的频率,并且该信息应与一组系数值交叉,以确保观察到所有可能的组合。BiQuad IIR滤波器测试计划中总结了该策略。
就采样而言,特定滤波器类型的覆盖组应仅在滤波器已配置为该模式时进行采样,并且应在输入频率穿过频率增量边界时进行采样。
Coverage Criterion |
BiQuad Filter Coverage |
Which values are important? |
The calculated discrete values for the filter co-efficients, ordered by filter type. Several discrete frequencies. |
What are the dependencies between the values? |
The co-efficients should be crossed with the input frequency to check all options have been tested. |
Are there illegal conditions? |
No since we are representing a sub-set of a continuous range of values, but some filter/frequency values are out of range. |
When is the right time to sample? |
When the frequency sweep waveform is sampled at one of the frequencies of interest. |
When is the data invalid? |
The right covergroup needs to be sampled for the right type of filter (LP, HP, BP) |
See the example implementation
of the BiQuad functional coverage model for more details.
6.2 BiQuad IIR滤波器测试计划
作为验证计划过程的一部分,应创建功能覆盖/测试计划。对于BiQuad IIR滤波器,主要关注的是检查它是否可以配置为在音频范围内充当低、高和带通滤波器,以及它在每种模式下是否正常工作。
6.3 BiQuad IIR Filter测试计划
Section |
Description |
Coverage Type |
Priority |
Low Pass Filter Operation |
|
|
|
|
The filter can be configured and operates correctly as a low pass filter in the audio frequency range (0-20Khz) |
Covergroup |
1 |
High Pass Filter Operation |
|
|
|
|
The filter can be configured and operates correctly as a high pass filter in the audio frequency range (0-20Khz) |
Covergroup |
2 |
Band Pass Filter Operation |
|
|
|
|
The filter can be configured and operates correctly as a band pass filter in the audio frequency range (0-20Khz) |
Covergroup |
3 |
6.4 BiQuad IIR滤波器示例 covergroups
BiQuad IIR滤波器的功能覆盖模型基于确保刺激检查了3组变量的所有变化:
- 滤波器类型——低通、高通和带通
- 过滤器规格,根据系数——b10、b11、b12、a10、a11
- 输入频率,以赫兹为单位
要创建覆盖率模型,我们需要创建一组覆盖率组和一个覆盖率监视器。
6.4.1 covergroup 设计
每个过滤器配置由一组系数值表示。这些值实际上是唯一的,可以分为适用于三种滤波器类型中的每一种的值组,然后需要将这些值与滤波器输入频率交叉,以检查是否已获得所有可能组合的覆盖率。
一种方法是创建一个单一的覆盖组,每个过滤器类型有单独的覆盖点,每个过滤器系数值组合有一个箱子。然而,在任何特定时间,双四阶滤波器只能配置为在一种模式下工作,因此每种滤波器类型都有一个覆盖组,并且每种覆盖组中只有一个会在每个特定频率变化时采样。代码示例中所示的示例适用于低通滤波器类型,但其他覆盖组仅在系数值方面有所不同。
SystemVerilog covergroup是在类中声明的,它必须在类构造函数方法(new()中)中构造。低通过滤器covergroup在包装器类中实例化,这允许在需要时通过构造包装器对象来创建它。covergroups sample()方法随后链接到包装器对象的sample()方法中。这是在类环境中实现covergroups的推荐方法。
在covergroup内部,有一个频率的coverpoint,它有一组对应于每个感兴趣的输入频率的箱子。系数的覆盖点基于所有系数的合并值(一个80位的值),而箱对应于从200 Hz膝盖频率到20 Khz的不同配置的系数值。两个覆盖点的叉积是LP_X。
6.4.2 功能覆盖监视器设计
用于对不同covergroups进行采样的functional coverage monitor组件是uvm_订户组件类的扩展。监视器有一个write()方法,每当测试台中的频率监视器检测到输入频率的变化时,就会调用该方法。监视器包含每个过滤器类型covergroup的covergroup包装。写入方法检查过滤器在哪种模式下进行测试,然后对相应的covergroup进行采样。由于双四元滤波器的系数存储在寄存器中,因此系数值存储在UVM寄存器模型中,然后在调用其sample()方法之前分配给相应的covergroup包装对象。write()方法可以有效地确保在输入频率发生变化时对正确的covergroup进行采样。
尽管功能覆盖模型已经作为一个UVM类实现,但同样的原则也可以应用于基于模块或接口的实现。
Biquad示例的源代码可以从这里下载:
( download source code examples online at https://verificationacademy.com/cookbook/code-examples).
7 SoC 覆盖率示例
系统级功能验证可以充分利用这样一个事实,即整个设计是一个独立的单元,将由客户使用,因此具有一些客户将遵循的逻辑使用模型。此外,作为一个系统,它通常由受信任的IP组成,验证重点更多地针对块互连和任何新功能。在系统级工作,自然会使用自上而下的方法创建一致的覆盖模型电子表格/测试计划。验证过程的预期结果是,通过执行系统设计意图和行为的可行子集,对系统进行了彻底验证。功能覆盖模型是仪器的一部分,用于确定设计是否已验证到所需的质量水平。
一般来说,SoC级别的验证策略与块级别的验证策略截然不同。在SoC级别,通常情况下,您是在重用块,并且真正感兴趣的是验证重用的块是否正确地互连在一起,系统的不同部分是否正确地相互交互,然后您是否获得了可接受的性能。在大多数SOC中,如果您包括所有模块的所有完整使用模型,那么总有比您有时间验证的更多用例场景,因此最重要的场景需要优先考虑。一般来说,你的重点可以根据哪些领域是新的(未经测试的IP、全新的RTL)或有问题的划分优先级。查看每个IP块的任何覆盖模型电子表格,并确定它们是否可以在SoC级别重用,这是一个好主意。一些工程师会将是否存在良好的覆盖模型作为选择IP的关键标准之一。
系统级设计示例是一个Wishbone片上系统(SoC),它包含一个基于RISC的处理器组件(带内存的CPU)、一个仲裁Wishbone结构和四个接口块(USB、以太网、I2C和VGA核)。
7.1 Wishbone SoC概述
A block diagram of the Wishbone SoC is below:
Wishbone SoC Block Diagram
请注意,这些块是使用仲裁叉骨总线结构互连的。带有DDR内存的RISC处理器组件连接到结构上,用于固件和流量存储,也用于接口核心。还有一种用于电源和时钟控制的侧逻辑。
以下是关于该设计的一些事实(就本例而言,这些事实是任意的):
- 可信任、可重用的IP
- 以太网、USB、I2C、VGA
- 新 IP:
- RISC处理器和内存:一次回退,所以应该是稳定的,但对我们来说是新的
- 新的项目特定设计:
- Wishbone面料,外加时钟和电源控制
- 测试台将使用可用的wishbone代理代替RISC处理器来驱动测试台。所以实际上,从验证刺激的角度来看,Wishbone SoC是一系列Wishbone单操作或块操作(读、写、读修改写)穿过结构
- 位于DDR的固件的可用性很晚,准备好后将折叠,但在大多数验证工作中不可用
- 互连、配置和吞吐量是主要关注点,尤其是功率和时钟控制,以最小化功耗
- 有一份Wishbone SoC架构文件,其中包含一些基本寄存器、电源和时钟实施信息
- 有5个IP核(处理器、USB、以太网、I2C、VGA)的IP块级文档,但它们是面向寄存器和接口的,设计细节最少。然而,I2C内核有一个测试计划电子表格,我们可以将其折叠到SoC测试计划层次结构中
7.2 功能覆盖模型创建:使用模型图
与大多数SoC架构文档一样,Wishbone SoC设计架构文档没有使用模型描述。架构师确实制作了一份两页的“数据表”,上面有方框图(上图)和一个包含一些使用模型信息的功能列表。因此,必须在首席设计架构师的帮助下生成一个高级使用模型。
Use Model Flow Diagram |
结果是这个流程图和步骤:
1. 设置/配置
- 引脚和默认寄存器值控制一些初始化
- 通过单写Wishbone操作设置固件寄存器
- 仲裁设置
- 时钟和电源设置
- 接口设置(USB、以太网、I2C、VGA核)
2. 通过记忆叉骨操作的流量(单个或块移动)
- DDR到接口
- 与DDR的接口
3. 突发事件
- 中断、错误等
该流程图有助于显示芯片的总体高级别使用,即使在这个级别上,也开始显示其流程和发散选择的覆盖范围。更进一步,流中的每个块都需要使用最能代表该区域内的设置或数据流的表格或图表进行扩展。覆盖模型测试计划创建的自上而下部分描述了此过程中通常使用的图表。以下各节说明了各种图表类型在WB SoC示例中的使用。
配置部分1: 表例子
Pin and Reg Configurations |
获取高级使用模型流中的每个子块,并使用最适合描述该子块信息的表格、图表或图表将其展开。例如,第一个“引脚和寄存器默认值”子块描述了如何在通电时初始化Wishbone SoC,并最好将其扩展到表中。这里使用了一个简单的表格,因为这个简单的通电和默认配置的空间很小。只有两个管脚可以选择固件的来源:在处理器的ROM中,预加载到DDR中,或者从I2C或USB读取到DDR中。启动电源状态在电源寄存器中硬编码为默认值,只有4个选项。同样,启动时钟寄存器有6位,每个区域一位(4个接口、结构和处理器子系统),可以打开或关闭,每个都有一个单独的默认速度寄存器。
然后,该表将引出测试计划中的一个部分和各个需求。参见下面的testplan电子表格图片中的第1.1、1.2和1.3节。
配置部分 2: Y 树例子
仲裁子块最好扩展为Y树图:
Arbiter Block Y-Tree Diagram |
这里,仲裁器配置选项显示在Y树图中。请注意强制和可选节点和选项的图例。在实践中,Wishbone采用循环仲裁,但图表显示了5种经典仲裁方案的更多可能性。所有5个仲裁方案都可以进一步扩展到许多其他子选项中。Y树图很适合显示选择和优先级。
然后,这个Y-树图将引出测试计划中的一个部分和各个需求。请参见下面的测试计划电子表格图片中的第2.1至2.2.5节。
配置部分3: 气泡图示例
Bubble Diagram Example |
大多数SOC解决各种时钟域和功耗问题,尤其是静态功耗问题。SOC的电源和时钟管理逻辑越来越复杂,因此需要在总体验证策略和测试计划中优先考虑。电源和时钟配置最好使用模拟芯片框图的气泡图来描述。WB SoC的六个区域中的每一个都显示了相应的电源和时钟配置信息。气泡图在这种情况下运行良好,显示了每个区域之间的关系,以及每个气泡显示了特定区域的电源和时钟设置。
这些气泡图将引出测试计划中的各个部分和各个需求。请参见下面的测试计划电子表格图片中的3.1-2节了解时钟,4.1-2节了解电源。
配置部分4: I2C 配置结合例子
I2C Configuration Combinations |
I2C模块配置使用Y-树和气泡图的组合来描述。顶部的Y树显示了I2C的常规和特殊CBU模式之间的选择。它还显示了允许的主机数量和速度选择之间的选择。然后,使用气泡图显示其他各种配置区域及其关系(与线条)。因为气泡图中的信息对于所有四个选项都是相同的,所以a*用于表示该信息对于其他三个选项是重复的。这说明了如何混合和匹配各种表格和图表样式,以最好地传达必要的信息。
然后,这个组合图将引出测试计划中的一个部分和各个需求。参见下面的testplan电子表格图片中的第5.3节。它在层次上参考了i2c IP附带的测试计划。
Traffic: I2C Sequence Diagram Example
I2C Sequence Diagram |
完成所有配置后,通信将启动。这是I2C读取或写入的示例序列图。该图显示了测试台之间的握手,从测试台测试控制器开始:
- 测试控制器通过通知I2C vip启动事务序列(读或写)来启动。
- I2C IP然后从结构请求总线,仲裁器在准备就绪时批准请求。
- 接下来,I2C IP向处理器发送一个写操作,声明方向(读或写)和大小等。
- 处理器运行一些固件,并通过CSR通知DDR启动传输。
- DDR从结构请求总线,仲裁器在准备就绪时批准请求。
- I2C然后通过单个或块操作(取决于大小和读写)发送或接收数据,并在完成时释放总线。
序列图(借用自UML)是显示数据移动和握手的好方法。如果有成百上千的数据序列,您不需要为每个序列绘制序列图,而是可以将它们划分为类似序列的类别,并为每个序列绘制“系列”序列图。你也可以在同一张图上显示两个方向(读和写),就像我们在上面为WB SoC做的那样。在上面的I2C示例中,我们可能会有其他序列图,其中包含数据速度受限、暂停、重试、错误等。固件也可能会指导其他类型的操作,并且每个都有自己的序列图。
SoC固件
与所有SoC一样,Wishbone SoC最终将由处理器上运行的软件驱动。该固件在项目后期才可用,并且有自己的开发和测试过程。将固件集成到验证过程中有几种可靠的方法:
- 如果处理器不受信任,可以创建一个处理器和内存子系统测试台,固件可以在可用时分阶段引入。固件可按低级别和高级别功能划分,优先级分为将在子集测试台上执行的操作,以及将使用其他方式(C模型测试、原型、首次通过芯片等)执行的操作。固件测试的这种分层可以用图表表示,并包含在覆盖模型测试计划电子表格中。
如果处理器受信任,则可以将其排除在主SoC测试台之外。这是用于Wishbone SoC的方法。将Wishbone VIP代理放置在处理器所在的位置,并创建一个控制状态寄存器(CSR)代理,以将CSR接口驱动到DDR。这两个代理按照顶级测试控制器/虚拟序列的指示协同工作,以模拟Wishbone总线和DDR内存上的处理器固件活动。这样的目标就是关注整体互联;解决了结构上的配置和吞吐量流量问题。
- 另一种方法是将实际的处理器RTL安装到位,并将伪固件放入DDR。这个初步的伪固件代码由必要的低级函数组成,用于执行基本的固件操作,如通过结构进行寄存器读写,以进行配置,或在DDR和四个接口之一之间进行基本数据移动。然后,测试台通过后门访问控制这些功能的运行。Questa的infact有一个软件驱动的验证包来解决这类问题。
无论使用哪种方法,无论是单独使用还是以各种组合使用,都必须尽早充实这些策略,并将其纳入总体验证架构和实施文档以及覆盖模型测试计划电子表格中。可以在任何testplan电子表格中添加几列,详细说明各种固件功能的使用、测试和覆盖方式和位置。
7.3 功能覆盖模型创建:电子表格
一旦Wishbone SoC的使用模型被充实到有用的图表和表格的渐进集合中,它们通常被输入到单个文档中,以便于查看和传播。有关解释,请参见“测试计划创建规范”页面上自上而下示例的结尾。然后,可以像同一链接的自底向上示例中所述的任何其他规范一样,对这个单一用例描述或生命中的一天(DITL)文档进行梳理,提取各种需求,以行的形式输入到Wishbone coverage model testplan电子表格中。每个图表都可以作为电子表格中的一个部分或子部分,图表中的各种表格内容和选项自然指向覆盖率组。下面是一个可能的示例:单击此处可获得更易于阅读的WB testplan pdf版本。您还可以下载下面的xml文件。
Wishbone SoC Testplan |
Wishbone SoC Testplan (continued) |
此电子表格显示了测试计划所需的基本内容。一个大型SoC的实际测试计划会更大(至少500行),但这个例子被简化为适合这里。有关各栏的用途和合法条目的一般说明,请参阅Coverage Plan Format文章。WB SoC测试计划电子表格中需要注意的事项:
- 请注意,许多描述中都引用了其他文件。此处无需再次输入冗余信息,只需参考文档和章节即可。
- 注意,描述简短且不正式。一些验证团队有一种优先语言,其中包含特定单词的特定定义。描述必须以其中一个关键词开头,例如“WB SoC应……”或者“i2c接口将只使用……”。
- 注意事项(第2.2.5节、第3.1节、第3.2节等)目前没有详细说明,留待将来扩展。这些可能会被分成更多行(2.2.5.1等),其中定义了特定的覆盖点。他们是从这里开始的,所以他们不会被遗忘。
- 注意链接的命名约定,dt表示定向测试,assert表示断言,cov表示以_cg或_cp结尾的功能覆盖组或点。为清晰起见,使用了“sfp”等独特的首字母缩略词表示静态固定优先级。这些术语使编写脚本来处理覆盖率信息变得更容易。这些约定应该在项目开始时确定,写下来,并在整个项目中统一使用。
- 请注意,第5.1-4行中单独的、较低级别的电子表格在此处按层次链接。i2c一款随VIP而来,另外三款将是全新的,但每款都将在各自的测试计划电子表格中。该链接确保它们会像在这个顶级测试计划电子表格中一样被折叠起来,并且节号会相互关联。
- 注意某些链接(1.3、2.14),每个特定要求有多个链接/类型。这是因为许多需求可能需要结合定向测试、覆盖点和断言来完全覆盖该需求的所有细节。
- 未显示:单一类型的项目(如覆盖点)可能涵盖多个需求。在这种情况下,每个需求行中将使用相同的链接名称和类型。
- 注意最后两列(所有者、优先级)。为了清晰起见,添加了这些文件,以记录与每个需求相关的有用信息。它们可以读入一个工具,比如Questa的验证管理工具。在那里,它们可以被分类和查看,并存储在符合UCIS的数据库中,但不在模拟器中使用。在这里,每个需求都有一个所有者,这样他们就可以根据自己的名字进行排序,只看到他们负责的需求。然后,优先级可以指导他们按照需求工作的顺序。
- 请注意,最后四行待定(待定),因为在本周会议期间没有足够的时间来充实这些行,所以将其留到下周。这很常见,但在进行过程中填写电子表格很重要。
单击此处获取WB SoC测试计划的副本,然后单击浏览器中的文件另存为保存此WBsoc。xml文件。您应该能够在Microsoft Excel中打开下载的文件。
电子表格自动化与重用
块级和VIP测试计划重用
一个常见的误解是,为块级测试台开发的功能覆盖测试台组件可以在更高的集成级别上自动重用。在实践中,一旦一个块的功能或接口协议被集成,就只能使用它的一个子集,这意味着如果功能覆盖组件被重用,就必须仔细检查它们,并且必须排除覆盖范围。任何块级测试计划也必须仔细检查,以确定是否值得导入SoC测试计划,或者是否最好单独包含相关条目。
现代VIP通常有自己的测试计划,该计划通常基于VIP中实现的协议覆盖率监视器或断言。这种类型的测试计划可以被重用为所描述的分层测试计划元素,然而,很可能只有协议的一个子集会被SoC实际使用。这可能意味着调整覆盖计划,以确保已在SoC级别检查了相关的运行模式。
自动创建测试计划
上面显示的测试计划电子表格中的功率气泡图和结果部分通常会导致以IEEE 1801 UPF格式捕获信息。需要验证系统电源状态和电源状态转换。它有助于建立一个平台,允许根据UPF信息自动创建测试计划。该电源架构测试计划可以与系统级测试计划的其余部分分层组合。如果失败,用户只需手动创建一个包含所有电源配置的测试计划。通常情况下,这是两种方法中的一种,手动输入和自动输入相结合。
EDA工具提供完整的验证解决方案并不少见,包括自动生成的覆盖模型和根据SoC设计需要调整的断言。通常情况下,这是为了更好地理解和有界的问题,如电源感知检查器、电源状态覆盖模型和时钟域交叉。电源和时钟验证工具,如Questa的电源感知和时钟域交叉(CDC),可以输出模拟可读的测试计划电子表格,该电子表格可以与其他测试计划分层链接,并读入Questa。这些自动生成的覆盖率模型测试计划及其相关断言可以链接到更高级别的SoC测试计划,以获得完成度。
智能测试台自动化
自上而下的覆盖模型创建方法的另一个重要好处是重用使用模型图。这些面向流的图实际上可以由智能测试台自动化工具(如Questa inFact)生成(或轻松转换为输入)。这些工具捕获并使用基于图形的使用模型流表示。这可以在不同的层面上完成。例如,图形可以表示接口级别(例如i2c接口)、块级别配置(i2c寄存器选项),甚至是顶层配置或流量场景(协调从一个外围设备或处理器到其他外围设备或处理器的数据配置和控制)。流程图可以分层连接,从而允许在测试台上实现一个充分使用的模型。这大大减少了实现测试台刺激生成部分所需的开发时间。此外,这些工具允许通过选择图形流中的各种路径来非常容易地定义覆盖范围,然后可以系统地运行模拟,以尽可能少的迭代次数达到覆盖目标。这导致实现覆盖关闭的模拟周期比典型覆盖目标的随机选择少10-100倍。
使用此过程时,仍然需要testplan电子表格。一个只包含类别和子类别的简单版本可以在前面生成,创建图表,然后在将覆盖范围添加到图表时更新电子表格。下面给出了WB SoC顶层图的一个示例。左边是图表的简单视图,它捕获了用于生成的合法配置空间选项。右图是叠加在图上的一组覆盖目标的示例(基本上是两个交叉覆盖,由紫色和蓝色区域表示)。
附录
1 要求的写作指南
要求的写作指南
在创建测试计划时,需要以一种有用、易于理解的方式记录成功芯片的需求。以下规则和指南将有助于确保实现这一点。在开始规划过程之前,核查小组最好先编制一份这样的清单,并将其分为规则(必须遵守)和建议(好主意)。实际上,这是在定义编写需求的需求。
- 不要重写源代码规范中已经详细说明的任何内容,只需参考原始文档即可。
- 划分类别和子类别,使每一行都是一个单独的需求。不要把五个要求写在一行上。每行写一个要求。
- 每个要求都应该是唯一的。不要使用十个要求,只要一个就可以了。衡量标准通常是它是否能轻易地链接到覆盖范围元素。
- 每个需求必须与某些覆盖元素(测试、覆盖组、覆盖点、交叉断言、代码覆盖等)相关联。
- 以大致相同的级别编写每个需求。不要在子系统级写一个,在与门级写下一个。如果你确实有多层次的需求,那就提出一个自然的三到五层次的量表,并清楚地定义它们。可以使用字母数字标记来区分级别,也可以将每个级别放在自己的分层测试计划电子表格中。
- 要求通常以肯定的形式书写,描述设计应做什么。然而,一些限制行为的要求更容易写在否定的字眼里;换言之,描述设计不应做的事情。
- 可以添加验证过程不会解决的要求。它可以通过C建模、实验室中的FPGA验证或其他方法来解决。无论如何都要包含它,并添加一列,说明该需求使用的是哪个流程。
- 用唯一的名称和唯一的编号系统识别每个需求。
- 需求可以细分为主要类别,如设计需求(关于设计)、验证需求(关于运行管理)、测试台需求(关于测试台)、软件需求(关于固件)、工具需求(关于Questa)、库需求(关于将使用的UVM的哪一部分)等。
- 应对需求进行排序或优先排序。这可能是一个1-3的量表,也可能是一个包含其他参数的复杂风险方程。
- 应订购要求。要有类别和子类别,不要只是偶尔输入,要有一些逻辑顺序。
- 每个设计需求都需要从三个验证角度来考虑,即生成、检查和覆盖。如何产生一种情况来执行这一要求?什么将检查它是否正确;一个断言,一个记分牌,还是两者兼而有之?需要涵盖什么样的排列,有多少排列?一些测试计划将有三个列,每个列都有一个简短的描述。
- 如果某个需求与某个重复使用的验证实体相关联,则应指定该需求。可以添加并填写关于当前或未来可重用性的列。
- 有专门用于特殊定向测试的要求是可以的,但这些要求不应广泛存在
- 测试台通常具有抽象级别,通常标有一些分层(L1-3)或命名(配置层、流量层等)。可以添加一个列,指定每个需求抽象层。
- 正常功能和错误处理功能要求应分开,但不要遗漏错误要求。
- 一些需求可能需要跨多个环境、区块、子系统、系统、实验室等进行移植。这一点应予以注意。指定的一列可以描述这一点。
- 有些要求可能是变相的限制。这很好。请注意。
- 有些要求是伪装的断言;它们具有因果性质,比如“在这之后,这将永远发生”。这很好,请注意。明智的做法是以某种逻辑方式对断言进行分类,如接口、内部等。
- 一些需求是面向配置的。您可能不需要指定每个配置,只需指出它们在其他文档中的描述位置,或描述每个独特的序列族。根据covergroups和coverpoints捕捉它们的方式进行划分。
- 一些需求是面向顺序的,这意味着它们是需要生成的配置或流量,以刺激设计。定义序列需求时,最好先按类别和子类别定义每个独特的序列系列,例如配置、通信量、中断、错误等更高的类别,然后根据需要将其分解为子类别。你不需要指定每一个序列,尤其是在其他文档中已经描述了它们的情况下,而是对它们进行分类,每一个都会产生一个有趣的封面
- 有些需求可能只是假设或要求,从而更容易实现。这很好。
- 应包括记分板或断言检查限制。记分板或断言的传递函数往往过于复杂,无法完全解决。指定要解决的问题和不解决的问题。对于记分板,将检查哪些实际事务级别的元素?
- 另一种更先进的方法是先考虑CoverGroup和coverpoints,然后再进行反向工作、逆向工程和编写需求。
w w w . v e r i f i c a t i o n a c a d e m y . c o m |
Le vent se lève! . . . il faut tenter de vivre!
Le vent se lève! . . . il faut tenter de vivre!