[UVM源代码研究] sequence、 sequencer与driver的通信(uvm-1.2版)_sequence访问driver变量-程序员宅基地

技术标签: UVM源代码研究  经验分享  源代码管理  

[UVM源代码研究] sequence、 sequencer与driver的通信(uvm-1.2版)

driver与sequencer间的基本连接与通信

driver与sequencer之间的通信,我们最常用的最基本的方法就是

  1. driver中的seq_item_port在agent中connect到了sequencer中的seq_item_export
  2. driver中的seq_item_port通过调用get_next_item任务来从sequencer上获取transaction

于是我们产生如下几个问题:

  • sequencer上的transaction从何处而来?
  • get_next_item这个任务如何实现数据的传递?
  • seq_item_port和seq_item_export分别是什么样的端口类型?

带着以上几个疑问我们看看uvm源代码中都是如何实现的。

get_next_item

src/seq/uvm_sequencer.svh中的源代码

在这里插入图片描述

src/comps/uvm_driver.svh中的源代码

在这里插入图片描述

经过TLM的学习我们知道在TLM通信中存在以下几个概念:

  1. initiator(调用通信方法)和target(实现通信方法)
  2. producer(产生数据)和consumer(使用数据)

由此我们得出如下结论:

  1. driver这里充当的是一个initiator和consumer的作用,发起get_next_item()的通信方法并获取数据,因而我们知道get_next_item()一定是在充当target的sequencer中实现的,并且数据也是在sequencer中产生。
  2. driver中seq_item_port是一个port类型,而sequencer中的seq_item_export是一个imp类型
    自定义的driver和sequencer中构造函数new中调用super.new()可以分别完成seq_item_port好seq_item_export的创建。

get_next_item_called

src/seq/uvm_sequencer.svh中的源代码

在这里插入图片描述

get_next_item这个的task里使用了get_next_item_called这个变量,212-214行显示调用get_next_item的时候get_next_item_called一定为0,否则会报错。调用完get_next_item后需要将get_next_item_called赋值为1。

我们再看看uvm_sequencer里还有哪些地方对get_next_item_called进行了赋值。

分别在item_done和stop_sequences这两个函数中对get_next_item_called做了赋0的操作,由此我们不难得出如下结论:driver执行get_next_item获取数据的时候,如果前一次get_next_item获取数据后driver中没有执行item_done或者sequencer没有调用stop_sequences来强制kill掉上面运行的所有transaction/sequence,那么sequencer中会报错。即通过get_next_item_called这样一个变量实现了driver一次只能从sequencer获取一个数据进行处理。

sequence_item_requeated

src/seq/uvm_sequencer_base.svh中的源代码

在这里插入图片描述

与get_next_item_called同时出现的另一个变量sequence_item_requeated起到一个等待sequencer授权sequence的作用。

sequence_item_requeated清零的位置与get_next_item_called一样,也是在item_done和stop_sequences中完成的,也就是正常情况下执行到get_next_item里的216行判断语句的时候sequence_item_requeated通常为0,会调用m_select_sequence,这个task是在uvm_sequencer的父类uvm_sequencer_base中实现的。

716-722行代码实现了等待被仲裁授权的sequence。

724-728授权上面等到的sequence(通过sequence对应的id标识arb_completed数组来实现授权)。
等待sequence授权的过程是get_next_item阻塞的原因所在。

get_next_item第221-222行实现了对get_next_item_called、sequence_item_requeated赋值为1,表明此时sequencer中有一个数据正在发送给driver处理,如果在item_done或者stop_sequences之前driver又通过get_next_item发起一个获取数据的请求,212和216行的判断会执行报错和不进行sequence的仲裁选择行为。

get_next_item第223行从m_req_fifo中用peek获取一个数据输出给driver。(注意这里用到的是peek而不是pop,也就是fifo中的数据仍然保留并没有彻底取出,后面会介绍原因。)

item_done

src/seq/uvm_sequencer.svh中的源代码

在这里插入图片描述

src/seq/uvm_sequencer_base.svh中的源代码
在这里插入图片描述

关于item_done,首先需要说明的就是这是一个函数,并不会消耗时间,driver中调用item_done表明通过get_next_item获取的transaction已经drive到interface完成了协议转换,可以接收下一笔数据了。

所以这里281-282行将前面介绍的这两个变量清零了。

284行就解答了我们前面关于get_next_item里为什么调用try_peek来从fifo中获取数据的问题:get_next_item只是表示driver获取了数据,但是数据什么时候被消耗完成是由item_done决定的,所以fifo中的数据只有在item_done的时候才能pop出来。

使用try_get函数同时增加了判断,如果此时取不出数据则报错。

288-289行这两个变量作用就是当sequence调用sequencer中的wait_for_item_done的时候,能够将item_done匹配到对应的sequene的某个特定transaction,正如我们在driver中如果使用rsp,需要调用rsp.set_id_info来将req和rsp通过id关联起来一样。

292-294行作用就是当item_done参数不为空时,就执行put_response()将item_done的参数作为rsp发出。

297行的作用就是授权给那些在等待授权队列里靠前位置调用了lock或者grab的sequence。

sequence与sequencer之间的通信

src/seq/uvm_sequencer_param_base.svh中的源代码

在这里插入图片描述

src/seq/uvm_sequence_base.svh中的源代码

在这里插入图片描述

sequencer中获取的数据存放在m_req_fifo这样一个uvm_tlm_fifo中。

关于这个fifo定义以及添加数据是在uvm_sequencer_param_base类中实现的,它派生自uvm_sequencer_base,而uvm_sequencer又是从它派生而来的。该类中还定义了另一个我们常用到的函数put_response(),后面我们会讲。

这里的send_request函数是在uvm_sequence_base(uvm_sequence的父类)调用的,这样就实现了在uvm_sequence的派生类中调finish_item(通常用uvm_do宏包裹)将数据发送到sequencer并存放在m_req_fifo中。

使用try_put()函数是为了进行判断fifo是否溢出,溢出则报错。

如此我们便清楚了sequence与sequencer之间数据传输的通路实现。

start_item

src/seq/uvm_sequence_base.svh中的源代码

在这里插入图片描述

finish_item实现将sequence中的数据发送到sequencer,而与之通常配对的start_item里都做了什么呢?它又是与sequencer做了哪些交互?

默认是用的是m_sequencer,即sequence启动时指定的sequencer。

这里主要执行操作就是994行等待sequencer的授权。

put_response

src/seq/uvm_sequencer_param_base.svh中的源代码

在这里插入图片描述

src/seq/uvm_sequence_base.svh中的源代码

在这里插入图片描述

从uvm_sequencer_param_base中put_response的实现我们发现,328行获取了通过rsp调用get_sequence_id获取了在该sequencer运行的对应的sequence的句柄,337行调用了对应sequence中的put_response函数并将该rsp压入了该sequence实例中的队列response_queue中,队列的默认允许深度是8。
进而在sequence中调用get_response才能获取到之前被压入的rsp数据。

这就是rsp从driver到sequencer再到sequence的数据通路,其实不难看出sequencer在这里只是起到了个调用函数的中介作用,甚至没有将rsp临时存放起来。

sequence、sequencer与driver数据通信图示

实现通过以上分析,我们对sequence、sequencer与driver数据的传递相关函数调用等总结为如下图示:
在这里插入图片描述

总结

本文通过分析UVM源代码中uvm_sequence、uvm_sequencer、uvm_driver中的相关代码实现,讲述了sequence中发包经sequencer、driver再到发包完整整个包的传递流程,相应经过本文的分析解释读者对UVM中transaction的传递会有更深的认识。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/sunstat/article/details/136867918

智能推荐

c# 调用c++ lib静态库_c#调用lib-程序员宅基地

文章浏览阅读2w次,点赞7次,收藏51次。四个步骤1.创建C++ Win32项目动态库dll 2.在Win32项目动态库中添加 外部依赖项 lib头文件和lib库3.导出C接口4.c#调用c++动态库开始你的表演...①创建一个空白的解决方案,在解决方案中添加 Visual C++ , Win32 项目空白解决方案的创建:添加Visual C++ , Win32 项目这......_c#调用lib

deepin/ubuntu安装苹方字体-程序员宅基地

文章浏览阅读4.6k次。苹方字体是苹果系统上的黑体,挺好看的。注重颜值的网站都会使用,例如知乎:font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, W..._ubuntu pingfang

html表单常见操作汇总_html表单的处理程序有那些-程序员宅基地

文章浏览阅读159次。表单表单概述表单标签表单域按钮控件demo表单标签表单标签基本语法结构<form action="处理数据程序的url地址“ method=”get|post“ name="表单名称”></form><!--action,当提交表单时,向何处发送表单中的数据,地址可以是相对地址也可以是绝对地址--><!--method将表单中的数据传送给服务器处理,get方式直接显示在url地址中,数据可以被缓存,且长度有限制;而post方式数据隐藏传输,_html表单的处理程序有那些

PHP设置谷歌验证器(Google Authenticator)实现操作二步验证_php otp 验证器-程序员宅基地

文章浏览阅读1.2k次。使用说明:开启Google的登陆二步验证(即Google Authenticator服务)后用户登陆时需要输入额外由手机客户端生成的一次性密码。实现Google Authenticator功能需要服务器端和客户端的支持。服务器端负责密钥的生成、验证一次性密码是否正确。客户端记录密钥后生成一次性密码。下载谷歌验证类库文件放到项目合适位置(我这边放在项目Vender下面)https://github.com/PHPGangsta/GoogleAuthenticatorPHP代码示例://引入谷_php otp 验证器

【Python】matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距-程序员宅基地

文章浏览阅读4.3k次,点赞5次,收藏11次。matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距

docker — 容器存储_docker 保存容器-程序员宅基地

文章浏览阅读2.2k次。①Storage driver 处理各镜像层及容器层的处理细节,实现了多层数据的堆叠,为用户 提供了多层数据合并后的统一视图②所有 Storage driver 都使用可堆叠图像层和写时复制(CoW)策略③docker info 命令可查看当系统上的 storage driver主要用于测试目的,不建议用于生成环境。_docker 保存容器

随便推点

网络拓扑结构_网络拓扑csdn-程序员宅基地

文章浏览阅读834次,点赞27次,收藏13次。网络拓扑结构是指计算机网络中各组件(如计算机、服务器、打印机、路由器、交换机等设备)及其连接线路在物理布局或逻辑构型上的排列形式。这种布局不仅描述了设备间的实际物理连接方式,也决定了数据在网络中流动的路径和方式。不同的网络拓扑结构影响着网络的性能、可靠性、可扩展性及管理维护的难易程度。_网络拓扑csdn

JS重写Date函数,兼容IOS系统_date.prototype 将所有 ios-程序员宅基地

文章浏览阅读1.8k次,点赞5次,收藏8次。IOS系统Date的坑要创建一个指定时间的new Date对象时,通常的做法是:new Date("2020-09-21 11:11:00")这行代码在 PC 端和安卓端都是正常的,而在 iOS 端则会提示 Invalid Date 无效日期。在IOS年月日中间的横岗许换成斜杠,也就是new Date("2020/09/21 11:11:00")通常为了兼容IOS的这个坑,需要做一些额外的特殊处理,笔者在开发的时候经常会忘了兼容IOS系统。所以就想试着重写Date函数,一劳永逸,避免每次ne_date.prototype 将所有 ios

如何将EXCEL表导入plsql数据库中-程序员宅基地

文章浏览阅读5.3k次。方法一:用PLSQL Developer工具。 1 在PLSQL Developer的sql window里输入select * from test for update; 2 按F8执行 3 打开锁, 再按一下加号. 鼠标点到第一列的列头,使全列成选中状态,然后粘贴,最后commit提交即可。(前提..._excel导入pl/sql

Git常用命令速查手册-程序员宅基地

文章浏览阅读83次。Git常用命令速查手册1、初始化仓库git init2、将文件添加到仓库git add 文件名 # 将工作区的某个文件添加到暂存区 git add -u # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,不处理untracked的文件git add -A # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,包括untracked的文件...

分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120-程序员宅基地

文章浏览阅读202次。分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120

【C++缺省函数】 空类默认产生的6个类成员函数_空类默认产生哪些类成员函数-程序员宅基地

文章浏览阅读1.8k次。版权声明:转载请注明出处 http://blog.csdn.net/irean_lau。目录(?)[+]1、缺省构造函数。2、缺省拷贝构造函数。3、 缺省析构函数。4、缺省赋值运算符。5、缺省取址运算符。6、 缺省取址运算符 const。[cpp] view plain copy_空类默认产生哪些类成员函数

推荐文章

热门文章

相关标签