当前位置:网站首页 > 技术博客 > 正文

uvm实战



由于在工作中需要用到UVM仿真,就将自己的学习过程记录下来,写成了一个UVM学习的系列文章,文章中的绝大多数内容都来自《UVM实战》这本书,也从找了一些网上的公开资料,并从零开始搭一个UVM的验证环境,里面包含了UVM中许多功能的用法,相信能更好的帮助刚入门的工程师们理解UVM的工作机制。

先抛开UVM,回想一下我们在平时写完程序后,是不是肯定需要灌一个激励给DUT,然后再从DUT获取结果,并跟一个参考模块进行对比,检查结果是否正确。就像下面这个图:

image-

在UVM中,引入了sequence机制,这个机制的最大作用就是将test case和testbench分离开来。对一个项目而言,testbench是相对稳定的框架,而针对各个module要有不同的测试内容,所以具体的test case 的差异非常大。在UVM中, test和sequence类总是成对出现,实现了testbench和具体的test case的结合。test类中可以针对具体的测试内容对testbench做一些差异化配置,在sequence类中则是实现test case的具体细节。

因此,在UVM中,使用sequence来产生transaction,再由sequencer传给driver,再作为激励传给DUT。也就是说driver只负责驱动transaction,而不负责产生transaction。

image-

同时UVM中将sequencer、driver和监测激励的monitor封装到一个in_agent中,将监测DUT输出的monitor封装到out_agent中,以提高代码的可重用性,模型如下:

image-

我们再对上面这些模块做一些更详细的解释,暂时看不懂没关系,先有个概念就行,后面的东西学的多了,这些概念自然也就懂了。

component与object是UVM中两大最基本的概念,也是初学者最容易混淆的两个概念。uvm_object是UVM中最基本的类,读者能想到的几乎所有的类都继承自uvm_object,包括uvm_component。

uvm_component有两大特性是uvm_object所没有的:

从图中可以看出,从uvm_object派生出了两个分支,所有的UVM树的结点都是由uvm_component组成的,只有基于 uvm_component派生的类才可能成为UVM树的结点;最左边分支的类或者直接派生自uvm_object的类,是不可能以结点的形式出 现在UVM树上的。

UVM通过uvm_component来实现树形结构。所有的UVM树的结点本质上都是一个uvm_component。每个uvm_component都有 一个特点:它们在new的时候,需要指定一个类型为uvm_component、名字是parent的变量:

构成环境的组件都从uvm_component类继承而来,这是因为它们都从uvm_component类继承了phase机制,都会经历各个phase阶段,关于phase的内容,我们后面介绍。

image-

所有的driver都要派生自uvm_driver。driver的功能主要就是向sequencer索要sequence_item(transaction),并且将 sequence_item里的信息驱动到DUT的端口上,这相当于完成了从transaction级别到DUT能够接受的端口级别信息的转换。

所有的monitor都要派生自uvm_monitor。monitor做的事情与driver相反,driver向DUT的pin上发送数据,而 monitor则是从DUT的pin上接收数据,并且把接收到的数据转换成transaction级别的sequence_item,再把转换后的数据发送给 scoreboard,供其比较。与uvm_component相比,uvm_monitor几乎没有做任何扩充。

所有的sequencer都要派生自uvm_sequencer。sequencer的功能就是组织管理sequence,当driver要求数据时, 它就把sequence生成的sequence_item转发给driver。

一般的scoreboard都要派生自uvm_scoreboard。scoreboard的功能就是比较reference model和monitor分别发送 来的数据,根据比较结果判断DUT是否正确工作。

UVM中并没有针对reference model定义一个类。所以通常来说,reference model都是直接派生自 uvm_component。reference model的作用就是模仿DUT,完成与DUT相同的功能。DUT是用Verilog写成的时序电路,而reference model则可以直接使用SystemVerilog高级语言的特性,同时还可以通过DPI等接口调用其他语言来完成与DUT相同的功能。

所有的agent要派生自uvm_agent。与前面几个比起来,uvm_agent的作用并不是那么明显。它只是把driver和 monitor封装在一起,根据参数值来决定是只实例化monitor还是要同时实例化driver和monitor。agent的使用主要是从可重用性的角 度来考虑的。如果在做验证平台时不考虑可重用性,那么agent其实是可有可无的。

所有的env(environment的缩写)要派生自uvm_env。env将验证平台上用到的固定不变的component都封装在一 起。这样,当要运行不同的测试用例时,只要在测试用例中实例化此env即可。

所有的测试用例要派生自uvm_test或其派生类,不同的测试用例之间差异很大,所以从uvm_test派生出来的类各不 相同。任何一个派生出的测试用例中,都要实例化env,只有这样,当测试用例在运行的时候,才能把数据正常地发给DUT,并正常地接收DUT的数据。

image-

image-

上一节我们讲了UVM中的类,也可以看到UVM中各个类的继承关系。了解了这些,再来看UVM中的树形结构。UVM中的sequencer、driver、monitor、agent、model、 scoreboard、env等都是树的一个结点。为什么要用树的形式来组织呢?因为作为一个验证平台,树形结构是一种非常合适的管理方式。

UVM的完整树结构如下图所示:

uvm_top是一个全局变量,它是uvm_root的一个实例,而且也是唯一的一个实例 ,它的实现方式非常巧妙。而uvm_root 派生自uvm_component,所以uvm_top本质上是一个uvm_component,它是树的根。uvm_test_top的parent是uvm_top,而uvm_top的 parent则是null。

uvm_top提供一系列的方法来控制仿真,例如phase机制、objection防止仿真退出机制等。

层次结构相关的函数

UVM提供了一系列的接口函数用于访问UVM树中的结点。这其中最主要的是以下几个:

  • 上一篇: textview文字大小
  • 下一篇: yml格式怎么打开
  • 版权声明


    相关文章:

  • textview文字大小2024-12-06 18:01:02
  • phython入门2024-12-06 18:01:02
  • 文件描述符号2024-12-06 18:01:02
  • 地理空间数据索引2024-12-06 18:01:02
  • java设置代理2024-12-06 18:01:02
  • yml格式怎么打开2024-12-06 18:01:02
  • python里jieba库怎么用2024-12-06 18:01:02
  • vb二级证书有用吗2024-12-06 18:01:02
  • pwn rop入门2024-12-06 18:01:02
  • python创建虚拟环境venv2024-12-06 18:01:02