开源 VHDL 验证方法(OSVVM)
介绍开源 VHDL 验证方法 (OSVVM) 是一种智能测试平台方法,允许将“智能覆盖”与定向、算法、基于文件和约束随机方法混合。 OSVVM是专门用于VHDL验证的集成环境。OSVVM 是一组 VHDL 软件包,最初由 Aldec 和 Synthworks 开发。 OSVVM 可帮助您采用使用 VHDL 的现代约束随机验证技术。借助OSVVM,人们可以将高级验证方法添加到当前的测试平台中,而无需学习新语言或抛弃现有的测试平台模型。 OSVVM 支持与基于其他验证方法的功能相同的功能。其中包括事务级建模、约束随机测试生成、功能覆盖、消息过滤、记分板和FIFO、错误报告等。

为什么选择OSVVM?验证能力在各种设计中都是一个大问题。验证和调试设计总是比编写设计代码更困难。与 System Verilog 一样,直接用 VHDL 编写很容易出错。OSVVM 提供了一种方法和库,可以简化 VHDL 用户的整个验证工作。 OSVVM 证明设计人员可以通过一种语言和一种方法获得能力、简单性和简洁性。
OSVVM 与 UVM/OVM 关于处理器资源的比较
除非您正在从事大型 xxx 兆门 ASIC 设计、拥有大型验证团队或拥有大量可重用/验证 IP,否则我会忘记 UVM(或OVM/VVM)。
OSVVM 中的智能覆盖比 SV 中的约束随机更高效,但例如内存分配呢?还是任务切换?
SystemC 源自 C++,当然非常灵活,但是这个因素在仿真中那么重要吗?两个模拟核心之间的同步消息怎么样(如果它们是这样称呼的)?
双语言模拟不如单语言模拟高效,因为模拟器必须处理 2 个模拟内核。对于 SystemC 和 VHDL 来说,开销可能不是那么大,因为它们都基于相同的调度程序模型,但是,(System)Verilog却截然不同(有更多的调度程序阶段)。
VHDL 和 Verilog/SV 之间的仿真性能差异大部分是由于 VHDL 使用的数据类型(SLV 等)、它们消耗多少内存等造成的。
但大多数好的测试平台都会最大限度地减少 SLV/无符号等的使用。并尽可能使用变量、整数和布尔值。这极大地缩小了 VHDL和 Verilog/SV 之间的性能差距。
值得庆幸的是,OSVVM 本身支持整数覆盖和随机化,因此它应该与 SV/UVM 更具可比性(特别是当 DUT 采用VHDL 格式时),如果使用智能覆盖,速度甚至更快。
Aldec Riviera-PRO 使用OSVVM指南
入门
在 Riviera-PRO 中开始使用 OSVVM 的第一步是确保您使用的是 VHDL 2008 或更高版本。对于使用 Riviera-PRO 以外的模拟工具的用户,您可能需要专门从OSVVM 网站下载 OSVVM。
·       需要理解的关键概念是以下包。它们始终添加到任何OSVVM 设计中,因为它们代表必要的 OSVVM 库包:
库osvvm; 使用osvvm.RandomPkg。全部; 使用osvvm.CoveragePkg。全部; OSVVM包信息:
RandomPkg包
RandomPkg 使用名为 RandomPType 的受保护类型来实现其随机化功能。使用受保护类型允许将种子存储在受保护类型内部,从而允许使用函数完成随机化。要使用RandomPkg,首先必须引用OSVVM库和RandomPkg,如下所示:
库 osvvm;使用 osvvm.RandomPkg.all;要进行随机化,进程必须声明自己的局部随机化变量。每个进行随机化的进程都需要自己的随机化变量和唯一的种子值。一种简单的方法是为进程命名并使用RV'instance_name 作为 Initseed 的参数(例如RV.InitSeed(RV'instance_name);)。随机化是通过重载函数之一完成的,例如 RandInt(例如RandInt :=RV.RandInt(0,255); )。

CoveragePkg包
CoveragePkg 是根据 Perl Artistic 开源许可证发布的。这是免费的。您可以从http://www.synthworks.com/downloads 下载它。它会不时更新。目前有许多计划的修订。 CoveragePkg 有助于编写功能覆盖率。实际上,功能覆盖可以使用任何代码编写。CoveragePkg 和语言语法只是为了简化这项工作。功能覆盖率建模的基本步骤是声明覆盖率对象、创建覆盖率模型、累积覆盖率、与覆盖率数据结构交互以及报告覆盖率。使用存储在覆盖范围对象内的数据结构对覆盖范围进行建模。覆盖率对象是通过声明CovPType 类型的共享变量来创建的,如下所示:
tb的架构测试是 共享 变量CovBin1 : CovPType ; 约束随机验证
近年来,约束随机验证(有时称为测试平台自动化)在复杂的验证环境中变得流行。约束随机验证的基本思想是使用随机化作为验证方法的基础。传统测试使用所谓的“定向”测试- 即编写测试的人必须准确决定应用什么刺激。受限随机验证使用随机输入。这样做有很多好处:
·       如果模拟时间更长,则会生成更多测试向量。
·       您可能会发现由于意外的输入组合或极端输入值而导致的错误。通过定向测试,仅仅测试您期望发生的事情就太容易了,而不是尝试测试您不期望发生的事情。
·       一旦开发了自动化测试,它仍然可以用于定向测试。
约束随机测试的主要缺点是您需要有一个自检测试平台。优点是自检测试平台是验证复杂系统的好方法,但这要求您拥有被测设计 (DUT) 的参考模型。考虑到上述所有解释,仍然存在一个问题。“约束”这个词是什么意思?随机化就是随机化 DUT 的测试向量。因此,话虽如此,很难知道哪些内容没有经过测试。为了避免这种情况并覆盖每个测试点,我们使用某些约束(也称为功能覆盖)随机化测试向量。功能覆盖率衡量与特定规范点相关的内容,以告诉您该规范点是否已被覆盖。请注意,这与代码覆盖率不同,代码覆盖率仅告诉您是否每行代码都已执行,但与功能无关。即使您的每一行代码都已执行,您的DUT 也可能不正确! OSVVM 提供了一种收集验证环境中节点值的方法,以帮助您决定验证何时完成。

创建随机值
为了生成随机值,我们需要做的第一件事是包含适当的包。例如
库osvvm;使用osvvm.RandomPkg。全部;使用osvvm.CoveragePkg。全部; 接下来,我们声明适当类型的变量。 变量a1 : RandomPType;变量b1 : RandomPType;接下来,我们创建随机值:
A <= a1.Randslv( 0 , 255 , 8 );B <= b1.Randslv( 0 , 255 , 8 );上面几行显示了如何创建 8 位宽的随机逻辑值,其值范围从 0 到 255。

图 1.代码解释
创建约束和分布
上面的示例生成了整个范围内的值。尽管我们可能希望将随机项限制在特定范围或值。 RandomPType 允许我们准确指定要生成的值及其分布。
abc <= Rndabc.Randslv( 0 , 31 , 4 );def <= Rnddef.Randslv(( 0 , 1 , 2 , 3 , 5 , 7 , 9 , 11 , 17 , 23 , 29 , 31 ), 4 );第一个示例显示了 0 到 31 整个范围内的基本随机化。第二个示例显示左侧括号中已经提供了约束,右侧显示了 4 位的宽度。因此,还有许多其他选项可以操纵VHDL 测试平台中的随机化、约束和分布。

功能覆盖
功能覆盖是观察测试计划执行情况的代码。因此,您编写的代码用于跟踪是否已执行与设计或界面要求、功能或边界条件相对应的重要值、值集或值序列。如果没有功能覆盖,您不知道随机测试覆盖了哪些具体点,更重要的是,您不知道哪些点尚未覆盖。为了生成功能覆盖率,我们测量覆盖点。覆盖点具有使我们能够将数据值整理到容器中的功能。功能覆盖基本上分为三个阶段。I) 设置,ii) 样本和 iii) 报告覆盖范围。覆盖点对整数值进行采样。在采样过程中,对覆盖率进行采样。最后,Coverreport 进程在模拟停止时写出测量的覆盖率数据。

创建工作空间和设计
在 Riviera-PRO 中,各个设计及其资源可以组合在一起作为一个工作区。工作区允许同时添加和处理多个设计。
·       转到文件|新建并单击工作区。新的工作区向导启动。
·       输入工作区名称并选择要创建项目的位置。
·       完成后单击“确定”按钮。(见下图)

图 2.创建新工作区
·       将创建新的工作区。现在右键单击工作区选项并转到添加|新设计。将弹出以下窗口。

图 3.创建新设计
·       完成后单击“完成”按钮。
·       设计管理器现在显示工作区名称和附加的新设计。

图 4.设计管理器窗口
创建/添加文件到设计中
·       要创建新文件或现有文件或创建目录,请右键单击设计管理器中的任意位置,然后单击添加|新文件。
·       您还可以使用文件 |新菜单可打开新文件并将其保存到设计目录(下图)

图 5.创建/添加文件到设计

创建 HDL 源代码
如果要创建 VHDL/Verilog/System C 源文件,请双击添加|新文件选项。然而,这里我们提供了OSVVM FIFO 示例实现,因此我们已经有了该文件。所以我们选择添加|现有文件和附加实施所需的文件。

编译
编译是对源文件进行分析的过程。文件中包含的分析设计单元以模拟器可以理解的格式放入工作库中。

编译文件
·       如果要编译单个文件,请转到“设计管理器”中的“文件”,右键单击该文件并从快捷菜单中选择“编译”。
·       如果您通过右键单击给定设计的“设计”选项卡来选择“全部编译”,则编译器会自动对源文件重新排序,以确保编译设计单元的顺序正确。



图 6.使用设计管理器编译文件
初始化模拟
一旦成功编译了所有需要的设计单元,您就可以初始化仿真。在初始化模拟之前,请确保:
·       您选择了顶层设计单位。
·       如果您在没有选择任何顶级单元的情况下运行模拟,模拟器将通过一个对话框提示您选择一个。
·       要开始模拟过程,您必须从“模拟”窗口中选择“初始化模拟”。该命令启动仿真模型的细化和初始化。在精化过程中,模拟器加载设计单元并在计算机内存中构建仿真模型。在初始化过程中,模型中的所有对象都会获取其初始值,并且所有并发进程都会执行一次,直到挂起。

图 7.仿真窗口

图 8.初始化仿真
·       将您的测试平台设置为顶级层次结构。选择后,将弹出“层次结构”窗口。(下图)

图 9. 层次结构窗口
·       获得该信息后,右键单击您的测试平台模块并选择添加到|波形选项。波形窗口将打开。
·       您可以通过选择运行选项来运行模拟。单击该按钮,模拟将开始运行。

运行全部/运行/运行直到模拟
·       要在模拟中运行模拟一段时间,请从模拟菜单中选择“运行时间”选项。
·       要完成模拟会话,请从“模拟”菜单中选择“停止模拟”。
·       您可以重新启动模拟,从“模拟”菜单中选择“重新启动”。

图 10.运行 For/运行全部/运行直到仿真
波形查看器
·       执行上述所有步骤后,您可能会看到波形文件中的结果,如下所示。

图 11.波形查看器
·       要保存波形文件或使用当前波形设置进行操作,您可以选择“波形”菜单选项。