uvm中transaction的response和id的解读
在公司写代码的时候发现前辈有一段这样的代码:
....//其他transaction
`uvm_create(trans);........
`uvm_send(trans);
tmp_id = trans.get_transaction_id();
get_response(rsp,tmp_id);
如果前面有其他transaction,这段代码里的get_response不带id的话,就会错误地get到前面transaction的response,有点好奇原理,就去看了看源码。
先从driver入手,如果要返回response的话,要先new一个rsp,然后set_id_info,再put_response:
//参考张强白皮书
seq_item_port.get_next_item(req);
drive_one_pkt(req);
rsp = new("rsp");
rsp.set_id_info(req);
seq_item_port.put_response(rsp);
seq_item_port.item_done();
先看set_id_info这个函数,在uvm_sequence_item.svh里面,作用就是将req的两个id set到rsp里,我们主要关注transaction_id,继续往后走。
function void set_id_info(uvm_sequence_item item);if (item == null) beginuvm_report_fatal(get_full_name(), "set_id_info called with null parameter", UVM_NONE);endthis.set_transaction_id(item.get_transaction_id());this.set_sequence_id(item.get_sequence_id());endfunction
get_transaction_id在uvm_transaction.svh里面,返回了m_transaction_id,这个id是uvm_transaction里面的一个local integer变量,默认值为-1。这个id的更改在其他地方,稍后再讲解。
function void uvm_transaction::set_transaction_id(integer id);m_transaction_id = id;
endfunctionfunction integer uvm_transaction::get_transaction_id();return (m_transaction_id);
endfunction
然后看put_response函数,在uvm_sequence.svh里,调用了put_base_response函数。
virtual function void put_response(uvm_sequence_item response_item);RSP response;if (!$cast(response, response_item)) beginuvm_report_fatal("PUTRSP", "Failure to cast response in put_response", UVM_NONE);endput_base_response(response_item);endfunction
put_base_response在uvm_sequence_base.svh里,作用是将response压入队列中,队列默认长度为8,即response_queue_depth=8,当response在队列中的数量为8还继续压入队列后就会报错,一般发生在没有取response的情况下。
virtual function void put_base_response(input uvm_sequence_item response);if ((response_queue_depth == -1) ||(response_queue.size() < response_queue_depth)) beginresponse_queue.push_back(response);return;endif (response_queue_error_report_disabled == 0) beginuvm_report_error(get_full_name(), "Response queue overflow, response was dropped", UVM_NONE);endendfunction
接下来到sequence端,我们看看transaction的id和response是怎么get的。transaction_id,在uvm_transaction.svh里,就是返回m_transaction_id。get_response在uvm_sequence.svh里,调用了get_base_response,这里的参数列表里就有transaction_id了。
virtual task get_response(output RSP response, input int transaction_id = -1);uvm_sequence_item rsp;get_base_response( rsp, transaction_id);$cast(response,rsp);endtask
get_base_response在uvm_sequence_base.svh里,可以看到在没有指定transaction_id(id为默认值)的时候,返回的response是从队列直接pop的,指定了以后就遍历队列找id对应的response,这里就是最前面代码的机制。
virtual task get_base_response(output uvm_sequence_item response, input int transaction_id = -1);int queue_size, i;if (response_queue.size() == 0)wait (response_queue.size() != 0);if (transaction_id == -1) beginresponse = response_queue.pop_front();return;endforever beginqueue_size = response_queue.size();for (i = 0; i < queue_size; i++) beginif (response_queue[i].get_transaction_id() == transaction_id) begin$cast(response,response_queue[i]);response_queue.delete(i);return;endendwait (response_queue.size() != queue_size);endendtask
但是到目前为止,response阶段没有看到id是怎么来的,我们从transaction的create和send阶段找一下。这些宏在uvm_sequence_defines.svh里,可以看到create阶段不涉及id的操作,send里面调了函数,可能会有。因为我们send的是transaction,是uvm_sequence_item类型,uvm_sequence_base是其子类,所以在uvm_send_pri里case不会成功,首先进入start_item里。
`define uvm_create(SEQ_OR_ITEM) \`uvm_create_on(SEQ_OR_ITEM, m_sequencer)`define uvm_create_on(SEQ_OR_ITEM, SEQR) \begin \uvm_object_wrapper w_; \w_ = SEQ_OR_ITEM.get_type(); \$cast(SEQ_OR_ITEM , create_item(w_, SEQR, `"SEQ_OR_ITEM`"));\end`define uvm_send(SEQ_OR_ITEM) \`uvm_send_pri(SEQ_OR_ITEM, -1)`define uvm_send_pri(SEQ_OR_ITEM, PRIORITY) \begin \uvm_sequence_base __seq; \if (!$cast(__seq,SEQ_OR_ITEM)) begin \start_item(SEQ_OR_ITEM, PRIORITY);\finish_item(SEQ_OR_ITEM, PRIORITY);\end \else __seq.start(__seq.get_sequencer(), this, PRIORITY, 0);\end
start_item在uvm_sequence_base.svh里,貌似也不涉及id的操作,再看finish_item,也在vm_sequence_base.svh里。finish_item调用了sequencer的send_request函数,进去看看。
virtual task start_item (uvm_sequence_item item,int set_priority = -1,uvm_sequencer_base sequencer=null);uvm_sequence_base seq;if(item == null) beginuvm_report_fatal("NULLITM",{"attempting to start a null item from sequence '",get_full_name(), "'"}, UVM_NONE);return;endif($cast(seq, item)) beginuvm_report_fatal("SEQNOTITM",{"attempting to start a sequence using start_item() from sequence '",get_full_name(), "'. Use seq.start() instead."}, UVM_NONE);return;endif (sequencer == null)sequencer = item.get_sequencer();if(sequencer == null)sequencer = get_sequencer(); if(sequencer == null) beginuvm_report_fatal("SEQ",{"neither the item's sequencer nor dedicated sequencer has been supplied to start item in ",get_full_name()},UVM_NONE);return;enditem.set_item_context(this, sequencer);if (set_priority < 0)set_priority = get_priority();sequencer.wait_for_grant(this, set_priority);`ifndef UVM_DISABLE_AUTO_ITEM_RECORDINGvoid'(sequencer.begin_child_tr(item, m_tr_handle, item.get_root_sequence_name()));`endifpre_do(1);endtask virtual task finish_item (uvm_sequence_item item,int set_priority = -1);uvm_sequencer_base sequencer;sequencer = item.get_sequencer();if (sequencer == null) beginuvm_report_fatal("STRITM", "sequence_item has null sequencer", UVM_NONE);endmid_do(item);sequencer.send_request(this, item);sequencer.wait_for_item_done(this, -1);`ifndef UVM_DISABLE_AUTO_ITEM_RECORDINGsequencer.end_tr(item);`endifpost_do(item);endtask
send_request在uvm_sequencer_param_base里,可以看到req的transaction_id就是在这里设置的,值为m_next_transaction_id,且每次设置完就自加1,这个值在uvm_sequence_base.svh里,初值为1。
function void uvm_sequencer_param_base::send_request(uvm_sequence_base sequence_ptr,uvm_sequence_item t,bit rerandomize = 0);REQ param_t;if (sequence_ptr == null) beginuvm_report_fatal("SNDREQ", "Send request sequence_ptr is null", UVM_NONE);endif (sequence_ptr.m_wait_for_grant_semaphore < 1) beginuvm_report_fatal("SNDREQ", "Send request called without wait_for_grant", UVM_NONE);endsequence_ptr.m_wait_for_grant_semaphore--;if ($cast(param_t, t)) beginif (rerandomize == 1) beginif (!param_t.randomize()) beginuvm_report_warning("SQRSNDREQ", "Failed to rerandomize sequence item in send_request");endendif (param_t.get_transaction_id() == -1) beginparam_t.set_transaction_id(sequence_ptr.m_next_transaction_id++);endm_last_req_push_front(param_t);end else beginuvm_report_fatal(get_name(),$sformatf("send_request failed to cast sequence item"), UVM_NONE);endparam_t.set_sequence_id(sequence_ptr.m_get_sqr_sequence_id(m_sequencer_id, 1));t.set_sequencer(this);if (m_req_fifo.try_put(param_t) != 1) beginuvm_report_fatal(get_full_name(), "Concurrent calls to get_next_item() not supported. Consider using a semaphore to ensure that concurrent processes take turns in the driver", UVM_NONE);endm_num_reqs_sent++;// Grant any locks as soon as possiblegrant_queued_locks();
endfunction
这下搞清楚了,transaction_id初值为1,且一个sequence里面每个transaction_id的值均不相同,每发一个req,id都会加一,通过这个id可以来区分不同的transaction!
相关文章:
uvm中transaction的response和id的解读
在公司写代码的时候发现前辈有一段这样的代码: ....//其他transaction uvm_create(trans);........ uvm_send(trans); tmp_id trans.get_transaction_id(); get_response(rsp,tmp_id); 如果前面有其他transaction,这段代码里的get_response不带id的话…...
第四节(1):EXCEL中判断一个WORD文件是否被打开
《VBA信息获取与处理》教程(10178984)是我推出第六套教程,目前已经是第一版修订了。这套教程定位于最高级,是学完初级,中级后的教程。这部教程给大家讲解的内容有:跨应用程序信息获得、随机信息的利用、电子邮件的发送、VBA互联网…...
java.util.concurrent.locks.Condition详解
Condition翻译成中文是“条件”,一般我们称其为条件变量,每一个Condition对象都通过链表保存了一个队列,我们称之为条件队列。 当然了,这里所说的Condition对象一般指的是Condition接口的实现类ConditionObject,比如我…...
选择适合变更管理的产品开发工具的要点和建议
什么是变更管理? 变更管理是指导组织改进的学科。由于可观察到的行为变化,它会导致永久性变化。它确保您的组织以彻底、有序和可持续的方式学习和改进。成功的改进项目需要个人和团队保持一致,他们有共同的愿景,他们知道如何定义…...
小程序 词云图 echarts-for-weixin-wordcloud
GitHub - clydee-geng/echarts-for-weixin-wordcloud: echarts词云微信小程序版 这个是适配与小程序版的词云图,之前有找到ucharts来代替,但是ucharts的词云图功能有两个缺点:1.无法根据值的大小显示词云图的大小;2.显示的顺序是…...
VScode配置Jupyter
环境 安装步骤 1、插件安装 2、更改pip加速源 pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple 参考:vscode python配置pip源 【Python学习】Day-00 Python安装、VScode安装、pip命令、镜像源配置、虚拟环境 3、建…...
java模拟GPT流式问答
流式请求gpt并且流式推送相关前端页面 1)java流式获取gpt答案 1、读取文件流的方式 使用post请求数据,由于gpt是eventsource的方式返回数据,所以格式是data:,需要手动替换一下值 /** org.apache.http.client.metho…...
【好玩】如何在github主页放一条贪吃蛇
前言 🍊缘由 github放小蛇,就问你烧不烧 起因看到大佬github上有一条贪吃蛇扭来扭去,觉得好玩,遂给大家分享一下本狗的玩蛇历程 🥝成果初展 贪吃蛇 🎯主要目标 实现3大重点 1. github设置主页 2. git…...
顶顶通ASR安装配置说明
联系顶顶通申请Asrproxy授权,勾选asrserver模块。 下载语音识别模型 链接:https://pan.baidu.com/s/1IuDkDeytZOqf7tAbIb6h1Q 提取码:6vg6 安装asrproxy到/ddt/asrproxy,模型解压到 /ddt/asrproxy/model 对接mod_vad asrproxy.json 配置如…...
VMware和别的服务器 ,组建局域网那些事 。
利用VMware ,实现组件局域网、有可能会受限于WiFi(路由器) 。 通常不会,除非做了网关设置 相关知识: 禁用局域网隔离(LAN Isolation): 某些路由器提供了一个选项,允许您禁…...
自监督DINO论文笔记
论文名称:Emerging Properties in Self-Supervised Vision Transformers 发表时间:CVPR2021 作者及组织: Facebook AI Research GitHub:https://github.com/facebookresearch/dino/tree/main 问题与贡献 作者认为self-supervise…...
计算机视觉: 基于隐式BRDF自编码器的文生三维技术
论文链接: MATLABER: Material-Aware Text-to-3D via LAtent BRDF auto-EncodeR 背景 得益扩散模型和大量的text - image 成对的图片, 现在文生2D的模型已经比较成熟的框架和模型,主流的技术比如说stable diffusion 和 midjourney 以及工业领域runway 等…...
分类预测 | MATLAB实现KOA-CNN-BiLSTM开普勒算法优化卷积双向长短期记忆神经网络数据分类预测
分类预测 | MATLAB实现KOA-CNN-BiLSTM开普勒算法优化卷积双向长短期记忆神经网络数据分类预测 目录 分类预测 | MATLAB实现KOA-CNN-BiLSTM开普勒算法优化卷积双向长短期记忆神经网络数据分类预测分类效果基本描述程序设计参考资料 分类效果 基本描述 1.MATLAB实现KOA-CNN-BiLST…...
Java队列相关面试题
ArrayBlockingQueue 1、ArrayBlockingQueue是什么?它与LinkedList和LinkedBlockingQueue有何区别? ArrayBlockingQueue是一个基于数组的有界阻塞队列,可以在队列的两端进行插入和删除操作。 与LinkedList不同,ArrayBlockingQueu…...
水库大坝除险加固安全监测系统解决方案
一、系统背景 为贯彻落实《办公厅关于切实加强水库除险加固和运行管护工作的通知》(〔2021〕8号)要求,完成“十四五”小型病险水库除险加固、雨水情测报和大坝安全监测设施建设任务,规范项目管理,消除安全隐患…...
android native C++编程实现数据库加密sqlcipher
sqlcipher是sqlite的加版本,分为免费版和收费版。 这里研究的是开源的免费版 https://github.com/sqlcipher/sqlcipher Android码源默认提供了sqlite的native,jni和java版本,但没有提供sqlcipher,开发用到需要自己添加。 sqlc…...
第五节 C++ 循环结构(算法)
文章目录 前言介绍1. for 语句1.1 语法结构1.2 语法流程的执行过程1.2.1 案例 1:循环的正序输入和倒序输入1.2.2 案例2 : 求1~n的平方数1.2.3 案例 3: 求输入a和b,求a~b区间数. 1.3 for 循环案例练习1.3.1 求最大值与最小值1.3.2 计算奇数和和偶数和1.3.3 计算平均气温与最高气…...
接口与抽象类的区别
a、抽象类不能被实例化只能被继承;b、包含抽象方法的一定是抽象类,但是抽象类不一定含有抽象方法;c、抽象类中的抽象方法的修饰符只能为public或者protected,默认为public;d、一个子类继承一个抽象类,则子类…...
短视频账号矩阵系统源码saas===独立部署
前言: 短视频账号矩阵是指在不同的短视频平台上,一个个人或企业所拥有的账号数量和分布情况。由于不同的短视频平台受众人群和内容类型等因素不同,因此拥有更多账号可以在更广泛的受众中传播内容,提高曝光度和流量。短视频账号矩阵…...
香港专用服务器拥有良好的国际网络连接
香港服务器在多个领域有着广泛的应用。无论是电子商务、金融交易、游戏娱乐还是社交媒体等,香港服务器都能够提供高效稳定的服务。对于跨境电商来说,搭建香港服务器可以更好地满足亚洲用户的购物需求;对于金融机构来说,香港服务器…...
日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...
树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频
使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...
练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...
【JavaSE】绘图与事件入门学习笔记
-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角,以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素。 坐标体系-像素 …...
如何在网页里填写 PDF 表格?
有时候,你可能希望用户能在你的网站上填写 PDF 表单。然而,这件事并不简单,因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件,但原生并不支持编辑或填写它们。更糟的是,如果你想收集表单数据ÿ…...
技术栈RabbitMq的介绍和使用
目录 1. 什么是消息队列?2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...
【p2p、分布式,区块链笔记 MESH】Bluetooth蓝牙通信 BLE Mesh协议的拓扑结构 定向转发机制
目录 节点的功能承载层(GATT/Adv)局限性: 拓扑关系定向转发机制定向转发意义 CG 节点的功能 节点的功能由节点支持的特性和功能决定。所有节点都能够发送和接收网格消息。节点还可以选择支持一个或多个附加功能,如 Configuration …...
Ubuntu系统复制(U盘-电脑硬盘)
所需环境 电脑自带硬盘:1块 (1T) U盘1:Ubuntu系统引导盘(用于“U盘2”复制到“电脑自带硬盘”) U盘2:Ubuntu系统盘(1T,用于被复制) !!!建议“电脑…...
Canal环境搭建并实现和ES数据同步
作者:田超凡 日期:2025年6月7日 Canal安装,启动端口11111、8082: 安装canal-deployer服务端: https://github.com/alibaba/canal/releases/1.1.7/canal.deployer-1.1.7.tar.gz cd /opt/homebrew/etc mkdir canal…...
ubuntu中安装conda的后遗症
缘由: 在编译rk3588的sdk时,遇到编译buildroot失败,提示如下: 提示缺失expect,但是实测相关工具是在的,如下显示: 然后查找借助各个ai工具,重新安装相关的工具,依然无解。 解决&am…...
