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===独立部署
前言: 短视频账号矩阵是指在不同的短视频平台上,一个个人或企业所拥有的账号数量和分布情况。由于不同的短视频平台受众人群和内容类型等因素不同,因此拥有更多账号可以在更广泛的受众中传播内容,提高曝光度和流量。短视频账号矩阵…...
香港专用服务器拥有良好的国际网络连接
香港服务器在多个领域有着广泛的应用。无论是电子商务、金融交易、游戏娱乐还是社交媒体等,香港服务器都能够提供高效稳定的服务。对于跨境电商来说,搭建香港服务器可以更好地满足亚洲用户的购物需求;对于金融机构来说,香港服务器…...
idea大量爆红问题解决
问题描述 在学习和工作中,idea是程序员不可缺少的一个工具,但是突然在有些时候就会出现大量爆红的问题,发现无法跳转,无论是关机重启或者是替换root都无法解决 就是如上所展示的问题,但是程序依然可以启动。 问题解决…...
SciencePlots——绘制论文中的图片
文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了:一行…...
STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...
Matlab | matlab常用命令总结
常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...
爬虫基础学习day2
# 爬虫设计领域 工商:企查查、天眼查短视频:抖音、快手、西瓜 ---> 飞瓜电商:京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空:抓取所有航空公司价格 ---> 去哪儿自媒体:采集自媒体数据进…...
pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)
目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关࿰…...
USB Over IP专用硬件的5个特点
USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中,从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备(如专用硬件设备),从而消除了直接物理连接的需要。USB over IP的…...
华硕a豆14 Air香氛版,美学与科技的馨香融合
在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...
【Java学习笔记】BigInteger 和 BigDecimal 类
BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点:传参类型必须是类对象 一、BigInteger 1. 作用:适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...
