0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

UVM序列的创建和运行及中断服务程序实现方案

电子设计 来源:EDN 作者:Rich Edelman 2021-04-09 16:09 次阅读

SystemVerilog通用验证方法(UVM)是一种生成测试和检查结果以进行功能验证的有效方法,最适合用于块级ICFPGA或其他“小型”系统。在UVM测试台中,大多数活动是通过编写序列来生成的,这些序列是验证程序的主力要素,会导致诸如刺激物产生和结果检查之类的事情发生。所以序列是您应该集中精力的事情。UVM有许多运动部件。考虑序列时,您可以专注于完成工作的程序。

产生序列项

导致其他顺序发生

管理其他音序器上的音序

产生乱序交易

我们还将向您展示如何编写自我检查序列的代码,并介绍在尝试更高级的用法之前构建和编写基本序列的基础。最后,这些技巧将帮助您更轻松地编码和调试UVM序列。

创建和运行UVM序列

如前所述,UVM序列是SystemVerilog代码的集合,该代码导致事件在测试平台内发生。它们通常用于创建事务,将其随机化,将其发送到定序器,然后再发送给驱动程序。在驱动程序中,生成的事务通常会引起接口引脚上的某些活动。

例如,如图1所示,write_read_sequence可以生成随机写事务并将其发送到定序器和驱动程序。驱动程序将解释写入事务有效负载,并导致使用指定的地址和数据进行写入。

pIYBAGBwCQGAMTa0AAFKBLL6hwc177.png

图1这是一个执行中的序列。

UVM序列是一个SystemVerilog对象,可以从许多不同的地方构造它,但是通常,测试可以构造序列然后运行它们-它们体现了测试。

例如,测试可能被伪编码为:

加载所有内存位置
读取所有内存位置,然后
检查预期的值是否匹配。

可能有一个顺序将所有存储位置从A写入到B。另一个顺序是将所有存储位置从A读取到B。或更简单的方法是:write_read_sequence首先写入所有存储位置,然后读取所有存储位置。

下面的测试在fork / join_none内部创建一个序列。将有四个并行运行的序列。每个序列都设置了一个LIMIT变量,并在fork / join_none的末尾开始运行。一旦完成所有分支,测试就完成了。

o4YBAGBwCRmAEMiZAAH6FNEW92g608.png

在下面的代码my_sequence中,它是一个简单的序列,可创建事务并将其发送到定序器和驱动程序。body()任务已实现。这是一个简单的for循环,它会循环LIMIT次。LIMIT是可以从外部设置的序列中的变量。

o4YBAGBwCT2AYNuvAAIK9TLAGiE205.png

在for循环中,通过调用new()或使用工厂来构造事务对象。然后,调用start_item以开始与音序器的交互。此时,定序器将停止执行序列,直到驱动程序准备就绪为止。一旦驱动程序准备就绪,定序器将使start_item返回。一旦start_item返回,则该序列已被授予使用驱动程序的权限。Start_item实际上应该称为request_to_send。现在,该序列具有使用驱动程序的权限,它可以使事务随机化,或根据需要设置数据值。这就是所谓的后期随机化,这是理想的功能。事务应尽可能接近执行随机化,这样它们可以捕获任何约束中的最新状态信息

在将事务随机化并设置了数据值之后,将其发送到驱动程序以使用finish_item进行处理。Finish_item实际上应该称为execute_item。此时,驱动程序将获取事务句柄并执行它。一旦驱动程序调用item_done(),然后finish_item将返回并且交易已执行。

执行驱动程序

驱动程序代码相对简单。它从uvm_driver派生并包含run_phase。run_phase是由UVM核心自动启动的线程。run_phase被实现为永远的开始-结束循环。在开始到结束块中,驱动程序调用seq_item_port.get_next_item(t)。这是一个将导致在音序器中执行的任务-本质上是向音序器询问应执行的下一个事务。可能是没有可用的事务,在这种情况下,此调用将被阻塞,即不会返回,因为它正在“等待某事”。(注意:可以使用其他非阻塞调用,但它们不在本文讨论范围之内,而不是建议的用法)。当定序器有要执行的事务时,那么get_next_item调用将取消阻塞并返回任务参数列表中的事务句柄(在下面的示例中为变量“ t”)。现在,驱动程序可以执行交易了。

对于此示例,执行很简单–它使用事务convert2string()调用打印一条消息,并等待由事务持续时间类成员变量控制的时间。
一旦执行完成,将调用seq_item_port.item_done()来发信号通知定序器,并依次返回序列,表明事务已被执行。

pIYBAGBwCUyAak18AAIpjDjN6z0164.png

虚拟序列及相关序列

序列可以具有其他序列的句柄;毕竟,序列只是一个具有数据成员的类对象,以及一个将作为线程运行的任务body()。

虚拟序列是一种序列,它可能不会生成序列项,而是在其他音序器上启动序列。这是从一个控制点创建并行操作的便捷方法。虚拟序列仅具有其他序列和定序器的句柄。它启动它们或以其他方式管理它们。虚拟序列可能已经通过从上方分配,使用配置数据库查找或其他方式获取了序列发生器句柄。它可能已经构造了序列对象,或者已经通过类似的其他方式获取了它们。

虚拟序列就像一个木偶大师,控制着其他序列。虚拟序列可能如下所示:

pIYBAGBwCViAbHilAADVw1jcZM8258.png

在下面的代码段中,有两个序列,即ping和pong。他们每个人都有彼此相处的地方。它们旨在轮流使用。第一个发送五个事务,然后另一个发送,依此类推。有关完整代码,请参见附录。

首先构造手柄,并设置运行极限。

自检和流量生成器序列

自检序列是导致一些活动,然后检查结果是否正常的序列。最简单的自检序列在一个地址处发出写操作,然后从同一地址进行读操作。现在将读取的数据与写入的数据进行比较。在某些方面,序列成为黄金模型。

pIYBAGBwCYCAJAwAAAIRorafZ1U522.png

可以编写视频流量生成器以生成背景流量流,该流模拟或建模视频显示可能需要的数据量。视频有最低带宽要求。该计算将随接口或总线上的负载而变化,但是对于此示例而言,简单的计算就足够了。视频流量将每秒生成60次数据屏幕。每个屏幕将具有1920×1024点。每个点由一个32位字表示。使用这些数字,流量生成器必须每秒创建471MB。

pIYBAGBwCZaAJrDaAAGux53jh_c657.png

更加完善的流量生成器将根据当前条件调整到达率-随着其他流量的上升或下降,应调整视频流量的生成率。

同步序列

序列将用于同步其他序列(所谓的虚拟序列)。通常,两个序列之间必须有正式的关系。例如,他们不能一起进入其关键区域-他们必须成为单一文件。否则,它们只能在一些常见的关键区域通过后才能运行。

下面的代码声明了两个要同步的序列(synchro_A_h和sync_B_h)。它还声明了一个同步器。这些类没有什么特别的-它们只是同意使用某种技术进行同步。

同步器控制非常简单。它只是说GO 20滴答声和STOP 100滴答声。

pIYBAGBwCbaAMiP3AACfitTZ-7w129.png

同步的序列开始。他们运行完成,然后只需重新启动即可。他们永远运行。

使用同步器的类只有在被告知执行后才能执行。

pIYBAGBwCdqAPUM1AAHhCTpSXSA419.png

仿真中,序列等待直到同步器处于GO状态。进入GO状态后,同步代码将使用new生成事务,然后调用start_item / finish_item来执行该事务。在等待访问驱动程序并执行之后,同步序列返回到循环顶部并检查同步器状态。它将再次运行或停止/等待(图2)。

o4YBAGBwCeWAA-ZmAACeuU3U82w534.png

图2仿真中的同步器等待GO状态。

实现中断服务程序

序列将用于提供中断服务程序。中断服务程序会一直休眠直到需要时为止。这是一种独特的序列。在此示例实现中,它创建一个中断服务事务并执行start_item和finish_item。这样,它可以将该ISR事务句柄发送给驱动程序。然后,驱动程序将握住该句柄,直到发生中断。

驱动程序将其作为处理SystemVerilog接口的整体工作的一部分来处理中断。在这种情况下,处理中断意味着将一些数据放入保留的句柄中,然后将该句柄标记为完成。同时,中断服务序列一直在等待事务被标记为完成。用某种说法,这被称为真正完成的项目。在UVM中,还有其他机制可以处理此类问题,但它们比这种解决方案更不可靠且更复杂。

pIYBAGBwCkiAPVYVAAEyEhJV_m4537.png

实用程序库

序列实用程序库将被创建和使用。实用程序库是一些简单的代码,可用于序列编写器,辅助函数或验证过程的其他抽象。

下面的open_door序列正如其名称所暗示的那样工作。它为音序器和驱动器打开了大门。现在可以使用序列对象句柄(例如seq.read()和seq.write())随意进行外部调用。

o4YBAGBwCmCAN721AAIT2OzqW34110.png

打开open_door,然后使用常规方法启动。然后,测试程序可以像下面的红线一样简单地发出读写操作。

pIYBAGBwCnCAWoSkAAFEdsrgpZk851.png

从序列中调用C代码

从序列调用C代码(使用DPI-C)很容易,但是有一些限制。DPI导入和导出语句不能放置在类内部,因此在文件,全局或包范围内,它们必须在类之外。因此,它们没有设计或类对象范围。

o4YBAGBwCoGAM4shAABns5eM-Cw754.png

DPI-C导出功能或任务只是使用export命令导出的SystemVerilog功能或任务。

pIYBAGBwCouAUE_EAABDX4x0eZk288.png

DPI-C导入函数或任务是具有返回值的C函数。对于任务,返回值为“ int”(有关详细信息,请参见SystemVerilog LRM)。对于函数,返回值应为返回值。

下面定义了简单的void函数c_code_add()。它有两个输入,并在指针* z中返回一个值。此C函数调用导出的SystemVerilog函数sv_code()。

o4YBAGBwCpSAMMmWAABlyXui4dY467.png

dpiheader.h是检查DPI-C API的便捷方法。在此示例中,dpiheader.h(下图)非常简单。

o4YBAGBwCp6ACZBFAAAxwUvNLZk826.png

这个序列没有什么特别的特殊之处。它生成事务,但确实调用了C函数(下面的c_code_add红线)。就编写调用C代码的序列而言,实际上没有什么特别的事情要做。DPI-C代码必须正确编写,并且必须在适当的范围内声明。

o4YBAGBwCq2AU84YAAH8KTn5-j4772.png

顺序和交易记录

在本文讨论的示例代码中,每个序列并行运行-在单个定序器上同时运行。在下面的两个屏幕截图(图3和图4)中可以很容易地看到,每个序列是如何轮流发送并在驱动程序上执行事务的。

pIYBAGBwCrqAAFfiAAH7UH2WEog269.png

图3此展开视图显示了每个序列如何轮流发送和执行事务。

pIYBAGBwCsaABRuiAACj5aiPG30670.png

图4这是事务的放大视图。

Rich Edelman是西门子Mentor的高级验证方法学家。

编辑:hfy

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • FPGA
    +关注

    关注

    1603

    文章

    21326

    浏览量

    593242
  • UVM
    UVM
    +关注

    关注

    0

    文章

    181

    浏览量

    18965
  • 序列
    +关注

    关注

    0

    文章

    70

    浏览量

    19452
  • 中断程序
    +关注

    关注

    0

    文章

    34

    浏览量

    8612
收藏 人收藏

    评论

    相关推荐

    《Visual C# 2008程序设计经典案例设计与实现》---动态创建和删除文件夹及显示其是否存在

    《Visual C# 2008程序设计经典案例设计与实现》---动态创建和删除文件夹及显示其是否存在.zip
    发表于 07-08 13:31

    数字IC验证之“搭建一个可以运行uvm测试平台”(5)连载中...

    化时为该对象指定的名字。  当事物模型创建好了之后,需要为它创建对应的事物发生器,在uvm当中,这个事物发生器叫做sequence,在平台的运行过程当中,只有启动了某个sequence
    发表于 01-26 10:05

    请问一下在UVM中的UVMsequences是什么意思啊

    uvm_object基类扩展得到。UVM sequences不是在仿真的开始,而是在仿真的过程中生成并分配内存的,也没有类似uvm_component的层次结构。随着仿真的进行,将创建
    发表于 04-11 16:43

    DevEco Studio3.0Beta-OpenHarmony创建和运行HelloWorld

    开发环境配置好后,可以通过运行HelloWorld工程来验证环境设置是否正确。创建一个新工程1.在DevEco Studio的欢迎页,选择Create Project开始创建一个新工程。2.根据工程
    发表于 04-14 14:26

    vxworks中断服务程序

    中断服务程序用来处理来自硬件的中断,是设备驱动程序的重要组成部分。为及时响应外部中断,防止
    发表于 06-27 11:09 1314次阅读

    WindowsCE异常和中断服务程序

    WindowsCE异常和中断服务程序,中断和异常都是异步发生的事件,当该事件发生,系统将停止目前正在执行的代码转而执行事件响应的服务
    发表于 01-04 15:37 1515次阅读

    如何创建和使用Xilinx的UltraScale PCI Express解决方案

    了解如何创建和使用Xilinx的UltraScale PCI Express解决方案。 使用Vivado IP目录GUI创建和使用PCI Express IP内核。 打开示例设计并在Vivado软件中
    的头像 发表于 11-28 06:36 3475次阅读
    如何<b class='flag-5'>创建和</b>使用Xilinx的UltraScale PCI Express解决<b class='flag-5'>方案</b>

    中断时间间隔的中断服务程序实现免费下载

    本文档的主要内容详细介绍的是中断时间间隔的中断服务程序实现免费下载。
    发表于 08-06 17:34 1次下载
    <b class='flag-5'>中断</b>时间间隔的<b class='flag-5'>中断</b><b class='flag-5'>服务</b><b class='flag-5'>程序</b><b class='flag-5'>实现</b>免费下载

    Arduino板是什么如何使用IDE软件创建和上传Arduino程序到Arduino板

    本章我们将研究Arduino板和IDE软件,我们要用IDE软件创建和上传Arduino程序到Arduino板(Arduino用草图表示程序,我们还是继续用程序这个传统术语)。我们会学到
    发表于 05-14 18:11 4次下载
    Arduino板是什么如何使用IDE软件<b class='flag-5'>创建和</b>上传Arduino<b class='flag-5'>程序</b>到Arduino板

    单片机的中断程序如何运行

    单片机的中断就是类似的一个过程,发生中断时,就会打断正在执行的主程序,先处理完中断任务,返回主程序继续
    的头像 发表于 01-27 17:11 1w次阅读
    单片机的<b class='flag-5'>中断</b><b class='flag-5'>程序</b>如何<b class='flag-5'>运行</b>

    如何创建和使用LabVIEW中的LLB文件

    如何创建和使用LabVIEW中的LLB文件
    发表于 11-22 16:12 0次下载

    中断服务程序是如何被执行的 ?

    笔者在 《程序是如何在 CPU 中运行的(二)》中从 PC 指针寄存器的角度分析了一级函数调用和二级函数调用执行的过程,那么中断服务程序.
    发表于 02-07 11:02 2次下载
    <b class='flag-5'>中断</b><b class='flag-5'>服务</b>子<b class='flag-5'>程序</b>是如何被执行的 ?

    UVM中的虚拟序列:为什么,如何?

    大多数UVM测试平台由可重复使用的验证组件组成,除非我们正在对像MIPI-CSI这样的简单协议进行块级验证。考虑验证简单协议的场景;在这种情况下,我们可以忍受只有一个音序器将刺激发送给驱动器。顶级
    的头像 发表于 05-29 09:46 480次阅读

    UVM中的可重用序列

    众所周知,序列由几个数据项组成,它们共同构成了一个有趣的场景。序列可以是分层的,从而创建更复杂的方案。在最简单的形式中,序列应该是
    的头像 发表于 05-29 09:50 407次阅读

    创建UVM Testcase的步骤

    UVM中,Testcase是一个类,它封装了测试用例开发者编写的特定激励序列
    的头像 发表于 06-15 09:41 963次阅读
    <b class='flag-5'>创建</b><b class='flag-5'>UVM</b> Testcase的步骤