路科验证的个人空间 https://blog.eetop.cn/1561828 [收藏] [复制] [分享] [RSS]

空间首页 动态 记录 日志 相册 主题 分享 留言板 个人资料

日志

UVM和C-完美结合

已有 2001 次阅读| 2020-12-10 11:08 |系统分类:芯片设计| IC验证

 

摘要:

SystemVerilog [1]和 UVM [2]为验证团队提供结构和规则。它使得在许多测试中能获得一致的结果,并可以在团队之间共享验证。许多验证团队都在使用由C代码编写的验证套件。本文将讨论将基于C的测试和验证套件集成到常规UVM测试平台的各种方法

 

  1. 引言

本文将演示把DPI-C与标准UVM Testbench一起使用的技术和方法。 C代码将应用于底层事务生成器,高级事务生成器,记分板和监视器等模块中。 UVM测试台将同步运行-例如,UVM测试可能正在总线上传输后台流量,而C代码在创建正在测试的特定总线事务

 

 

UVM与C之间的问题

UVM被广泛用于测试平台创建,覆盖率收集和监测。使用SystemVerilog和UVM已成为提高验证团队生产力的一种方法。

除了UVM原生的随机化和约束功能之外,验证团队还需要创建或重用C程序。这些C程序可能用来产生激励、检查标准结果,也可能用来收集统计数据。使用System Verilog的DPI-C是将这两个世界连接在一起的方法。

问题是使用DPI-C有时会很困难,并且DPI代码与“作用域”密切相关作用域可以是模块(module)实例接口(interface)实例全局根(root)作用域这些作用域为DPI提供了一个从System Verilog来回调用的连接点。

UVM测试平台几乎没有这些作用域。 UVM测试台是基于动态类的结构,而不是基于静态实例的结构。

 

 

解决方案:虚拟接口

有许多可轻松连接UVM和C的解决方案。本文将探讨最简单的方法–利用与代理相关联的接口(虚拟接口)

 

  1. 背景

UVM测试平台通常是通过代理(Agent)附带一个System Verilog接口来构建的。该接口连接到被测设备(design under test,DUT)端口。为了给DUT发送消息,UVM利用驱动(driver)来控制引脚的时序波形。为了从DUT接收消息,UVM利用监视器(Monitor)来收集引脚的时序波形。接口实例是我们用来承载DPI-C调用的理想场所。

图1 - 典型的Agent与DUT之间利用接口链接

 

如图2所示,通过DPI-C添加C代码

图2 - 单个的Agent与C代码连接

 

可以将多个Agent(如图3所示)连接到C代码,无论是否线程化。 C代码不是特定于实例的。可能存在与某些接口关联的某些C代码(例如AHB与AXI)。

图3 - C代码与多个Agent相连

 

 

SystemVerilog 接口

SystemVerilog接口是一个收集信号的地方,这些信号被认为是一个整体,就像总线一样。它可以包含许多其他内容,包括modports和时钟模块,以及其他接口等。SystemVerilog接口可以像模块一样被“实例化”,并且可以连接到该接口。

就我们的目的而言,我们只关心接口提供托管的DPI导入和导出范围的能力。

 

 

上面的界面是一个简单的界面,其中包含导入和导出。它可以包含许多其他项目。辅助函数的作用将调用简单地转发到接口中已连接的序列发生器(sequencer)上。在界面中仅建议使用简单的封装。将功能保留在sequencer或agent代码中。

 

 

UVM Agent

我们在此解决方案中使用的Agent就是常规的AgentTransaction,Driver、Monitor或Agent的程序本身没有任何变化任何调用DPI代码的sequence都将需要改动,sequencer也将需要改动。

Agent需要处理一件新的任务。它在Sequencer中初始化虚拟接口句柄,并在虚拟接口中初始化Sequencer句柄。这就是将接口连接到Sequencer以及将Sequencer连接到接口的魔法。Agent负责将接口和Sequncer连接在一起。

从接口可以进行Sequencer调用,而从Sequencer可以进行接口调用。

Agent通常具有该功能,在build_phase中,我们添加了另外两行。

这两行代码连接虚拟接口和Sequencer。这是从“常规”的Agent到启用DPI-C的Agent中唯一添加或改动的地方。

 

 

UVM Sequencer

在此解决方案中,经常被忽视且备受争议的UVM Sequencer才是中心。这是我们决定DPI的“根” 连接的常见位置。实际上,agent的任何部分都可以作为根来使用。我们建立DPI连接的根,以便在接口和DPI代码之间建立一对一的关系。或者是Agent和DPI代码之间。这样,管理线程和作用域都很自由。无需多加管理,因为接口具有作用域,我们将其视为Agent的一部分(实际上是)。

首先,将虚拟接口的句柄添加到Sequencer中。然后可以创建任何辅助函数。辅助函数可以位于其他位置,但这是一个集中的位置,而且很方便。

 

 

有两种辅助函数。调用C代码的辅助函数(c_start_threads())和调用SV代码的辅助函数(sv_start_sequenceC())。

C示例代码使用虚拟接口句柄来调用托管的C代码。作用域是自动设置和管理的。在上图所示的示例中,一次启动了4个线程。

SV示例代码创建一个序列,然后启动它。在开始之前,任何成员变量或随机调用都可能发生。序列完成后,任何结果都可以从seq.b中复制出来。 C函数可以调用UVM sequencer的想法非常强大。辅助函数将C函数调用映射被单个或多个序列执行。这是该解决方案的关键部分。创建可以执行有用功能的序列,使用辅助函数从C代码调用它们,然后使用接口确定作用域并将Sequencer作为辅助函数的基类。

 

 

UVM Sequence

该解决方案中的UVM序列没有任何更改,除非需要调用C代码。如果要调用C代码,则使用虚拟接口句柄。

在此解决方案中,序列可以从运行其的序列器中检索虚拟接口句柄。

这个例子中c_datatype_array_of_10_int是被调用的函数,示例的C代码直接从UVM Sequence中通过vif被调用。

这个简单的代码只是将输入复制到输出并更新输入/输出参数。

 

  1. C语言部分代码
 

简单的带作用域的Hello World代码

简单的hello world,实际上不仅仅是简单的hello world。这是编写C代码的方式,并且可以使用DPI-C调用SystemVerilog。在SV DPI-C规范中,有一些API调用,例如svGetScope()和svGetNameFromScope()有时还是有用的。通常,你不需要任何API调用。这就是使DPI变得简单而强大的原因之一。您只是在使用C代码。仅此而已。

当SystemVerilog代码要调用C时,使用“导入(import)”来实行调用。当C代码要调用SystemVerilog时,使用“导出(export)”来实现调用。

在上面的代码中,c_hello()是导入,而sv_hello()是导出在C代码中,需调用SystemVerilog函数或任务时,我们直接调用即可。

可以编写C代码来执行任何有用的验证功能-例如读取标准结果文件,生成激励或收集统计信息。使用我们的解决方案,C代码还具有调用序列的功能。任意序列都可用,并且定义了辅助功能。

 

 

线程代码

C代码通常不是线程安全的。在SystemVerilog中,创建线程和线程化应用非常容易。但是这些线程化的应用程序必须是“合作的”。当SystemVerilog“线程”启动时,它可以控制单个计算。不同线程获得控制权的唯一方法是让当前线程放弃控制权或让步。

让步可以采取多种形式。如果SystemVerilog线程执行#delay,wait()或@(posedge clk),则该线程将让步,下一个线程将能够获得控制权并运行。

在上面的sequencer代码中,有一个辅助函数来启动C线程。

执行此代码时,将创建4个线程。它们每个依次运行。 (直到运行的那个让步。一次只能运行一个线程)。

在示例代码中,任务c_thread()调用辅助函数sv_start_sequenceC()。这将创建一个序列并运行它。按照这种顺序,将创建事务并将其随机化,然后start_item()和finish_item()会将它们发送给driver,然后发送给接口引脚和DUT。

但是C代码不需要担心这些细节。 C代码是一段调用内置辅助函数的代码。 C代码和辅助函数必须以线程安全的方式编写。在此示例中,我们使用了一个名为'jj'的全局变量,该变量不是线程安全的-它的值将从线程进入睡眠状态到唤醒线程的时间发生变化。线程休眠时,如果该线程的状态更改,则代码不是线程安全的。

 

下面是使用老式的初始代码块产生让步的示例

使用SystemVerilog fork / join会产生相同的结果。

 

图4 粉红色表示C生成的序列,蓝色和紫色表示SystemVerilog生成的序列

 

在图4中,示例代码正在运行,并且对于每个Agent,都有一行彩色的类句柄。颜色表示当时在该Agent上运行的序列的类型。C生成的序列用粉红色表示,SystemVerilog生成的序列用蓝色和紫色表示。它们都在轮流使用,在接口上对所有后台或“正常”流量以及新的基于C的序列进行排序。

这种无缝集成UVM后台流量和C生成流量的功能是此解决方案的关键点。

 

 

C代码

C代码的目标是以某种方式与DUT进行交互。通过生成输入或监视输出,或两者兼而有之。与DUT的交互受UVM的控制,因此来自C的任何交互都必须遵循规则。使用UVM Sequencer和Sequence是一种简单有效的方法。

所有可能镜像到C的操作都必须分解为子处理,每个子处理均由UVM序列表示。例如,从C到DUT的大数据传输将被实现为对“大传输”序列的调用,或者对按字节传输序列的许多调用。

C总线传输是对总线上传输或交互的考研。例如,读操作或写操作。每次往返C的调用都是一次总线转接。 对C的调用依次创建并执行一个总线传输序列。

有很多情形可以使用C代码,所有这些场景都超出了本文的讨论范围。其中的一些示例包括:

 

  • 激励生成器简化激励的生成。数据由C语言一侧生成,并通过DPI-C的调用发送到SV一侧。

  • 数据监测:通过C编写标准模型。数据从DUT中被监测采集并通过导入的任务或者函数,发送到C语言一侧。

  • 总线传输生成器:C语言一侧的程序发出总线的READ和WRITE操作。 C程序几乎无法感知它正在System Verilog仿真中运行。

 

  1. 结论

使用DPI-C既简单又强大。使用System Verilog界面,可以消除许多集成和连接问题使用上述的技术,可以轻松创建大型的线程C测试。请联系作者以获取可下载的源代码,以开始使用DPI-C进行试验。

 

  1. 参考资料

 

  1. 附录
 

C代码

 

 

SV接口

 

 

UVM测试平台

 

 

 

扫描上图二维码可直达课程页面,马上试听

 

往期精彩:

路科发布| 稳中带涨!25w成芯片校招薪资平均底!2020应届秋招数据全面分析!

相约今晚8点 2020 IC秋招经验分享与数据分析

V2Pro 2020秋M1 我对你的迷惑和选择都深以为然

V2Pro春季班普遍学撑了,秋季班7月报名你还敢来么

UVM RAL模型:用法和应用

我们准备做第二期线下培训,依旧认真且严肃

如果你突然被裁员了,你的Plan B是什么?

[彩虹糖带你入门UVM]

理解UVM-1.2到IEEE1800.2的变化,掌握这3点就够

 

 


点赞

评论 (0 个评论)

facelist

您需要登录后才可以评论 登录 | 注册

  • 关注TA
  • 加好友
  • 联系TA
  • 0

    周排名
  • 0

    月排名
  • 0

    总排名
  • 0

    关注
  • 253

    粉丝
  • 25

    好友
  • 33

    获赞
  • 45

    评论
  • 访问数
关闭

站长推荐 上一条 /2 下一条

小黑屋| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-4-19 23:43 , Processed in 0.016237 second(s), 11 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
返回顶部