UVM中封装成agent
在验证平台中加入monitor时,看到driver和monitor之间的联系:两者之间的代码高度相似。其本质是因为二者 处理的是同一种协议,在同样一套既定的规则下做着不同的事情。由于二者的这种相似性,UVM中通常将二者封装在一起,成为 一个agent。因此,不同的agent就代表了不同的协议。
class my_agent extends uvm_agent ;my_driver drv;my_monitor mon;function new(string name, uvm_component parent);super.new(name, parent);endfunction extern virtual function void build_phase(uvm_phase phase);extern virtual function void connect_phase(uvm_phase phase);`uvm_component_utils(my_agent)
endclass function void my_agent::build_phase(uvm_phase phase);super.build_phase(phase);if (is_active == UVM_ACTIVE) begindrv = my_driver::type_id::create("drv", this);endmon = my_monitor::type_id::create("mon", this);
endfunction function void my_agent::connect_phase(uvm_phase phase);super.connect_phase(phase);
endfunction
所有的agent都要派生自uvm_agent类,且其本身是一个component,应该使用uvm_component_utils宏来实现factory注册。
这里最令人困惑的可能是build_phase中为何根据is_active这个变量的值来决定是否创建driver的实例。is_active是uvm_agent的一 个成员变量,从UVM的源代码中可以找到它的原型如下:
uvm_active_passive_enum is_active = UVM_ACTIVE;
而uvm_active_passive_enum是一个枚举类型变量,其定义为:
typedef enum bit { UVM_PASSIVE=0, UVM_ACTIVE=1 } uvm_active_passive_enum;
这个枚举变量仅有两个值:UVM_PASSIVE和UVM_ACTIVE。在uvm_agent中,is_active的值默认为UVM_ACTIVE,在这种模 式下,是需要实例化driver的。那么什么是UVM_PASSIVE模式呢?以本章的DUT为例,如图2-5所示,在输出端口上不需要驱动任 何信号,只需要监测信号。在这种情况下,端口上是只需要monitor的,所以driver可以不用实例化。
在把driver和monitor封装成agent后,在env中需要实例化agent,而不需要直接实例化driver和monitor了:
class my_env extends uvm_env;my_agent i_agt;my_agent o_agt;function new(string name = "my_env", uvm_component parent);super.new(name, parent);endfunctionvirtual function void build_phase(uvm_phase phase);super.build_phase(phase);i_agt = my_agent::type_id::create("i_agt", this);o_agt = my_agent::type_id::create("o_agt", this);i_agt.is_active = UVM_ACTIVE;o_agt.is_active = UVM_PASSIVE;endfunction`uvm_component_utils(my_env)
endclass
完成i_agt和o_agt的声明后,在my_env的build_phase中对它们进行实例化后,需要指定各自的工作模式是active模式还是passive 模式。现在,整棵UVM树变为了如图2-6所示形式。
由于agent的加入,driver和monitor的层次结构改变了,在top_tb中使用config_db设置virtual my_if时要注意改变路径:
initial beginuvm_config_db#(virtual my_if)::set(null, "uvm_test_top.i_agt.drv", "vif", input_if);uvm_config_db#(virtual my_if)::set(null, "uvm_test_top.i_agt.mon", "vif", input_if);uvm_config_db#(virtual my_if)::set(null, "uvm_test_top.o_agt.mon", "vif", output_if);
end
在加入了my_agent后,UVM的树形结构越来越清晰。首先,只有uvm_component才能作为树的结点,像my_transaction这种使 用uvm_object_utils宏实现的类是不能作为UVM树的结点的。其次,在my_env的build_phase中,创建i_agt和o_agt的实例是在 build_phase中;在agent中,创建driver和monitor的实例也是在build_phase中。按照前文所述的build_phase的从树根到树叶的执行顺 序,可以建立一棵完整的UVM树。UVM要求UVM树最晚在build_phase时段完成,如果在build_phase后的某个phase实例化一个 component:
class my_env extends uvm_env;…virtual function void build_phase(uvm_phase phase);super.build_phase(phase);endfunctionvirtual task main_phase(uvm_phase phase);i_agt = my_agent::type_id::create("i_agt", this);o_agt = my_agent::type_id::create("o_agt", this);i_agt.is_active = UVM_ACTIVE;o_agt.is_active = UVM_PASSIVE;endtask
endclass
如上所示,将在my_env的build_phase中的实例化工作移动到main_phase中,UVM会给出如下错误提示:
UVM_FATAL @ 0: i_agt [ILLCRT] It is illegal to create a component ('i_agt' under 'uvm_test_top') after
那么是不是只能在build_phase中执行实例化的动作呢?答案是否定的。其实还可以在new函数中执行实例化的动作。如可以在 my_agent的new函数中实例化driver和monitor:
function new(string name, uvm_component parent);super.new(name, parent);if (is_active == UVM_ACTIVE) begindrv = my_driver::type_id::create("drv", this);endmon = my_monitor::type_id::create("mon", this);
endfunction
这样引起的一个问题是无法通过直接赋值的方式向uvm_agent传递is_active的值。在my_env的build_phase(或者new函数)中,向i_agt和o_agt的is_active赋值,根本不会产生效果。因此i_agt和o_agt都工作在active模式(is_active的默认值是UVM_ACTIVE), 这与预想差距甚远。要解决这个问题,可以在my_agent实例化之前使用config_db语句传递is_active的值:
class my_env extends uvm_env;virtual function void build_phase(uvm_phase phase);super.build_phase(phase);uvm_config_db#(uvm_active_passive_enum)::set(this, "i_agt", "is_active", UVM_ACTIVE);uvm_config_db#(uvm_active_passive_enum)::set(this, "o_agt", "is_active", UVM_PASSIVE);i_agt = my_agent::type_id::create("i_agt", this);o_agt = my_agent::type_id::create("o_agt", this);endfunction
endclassclass my_agent extends uvm_agent ;function new(string name, uvm_component parent);super.new(name, parent);uvm_config_db#(uvm_active_passive_enum)::get(this, "", "is_active", is_active);if (is_active == UVM_ACTIVE) begindrv = my_driver::type_id::create("drv", this);endmon = my_monitor::type_id::create("mon", this);endfunction
endclass
只是UVM中约定俗成的还是在build_phase中完成实例化工作。因此,强烈建议仅在build_phase中完成实例化。
相关文章:

UVM中封装成agent
在验证平台中加入monitor时,看到driver和monitor之间的联系:两者之间的代码高度相似。其本质是因为二者 处理的是同一种协议,在同样一套既定的规则下做着不同的事情。由于二者的这种相似性,UVM中通常将二者封装在一起,…...

OSI七层模型与TCP/IP四层模型
一、OSI七层模型简述 OSI 模型的七层是什么?在 OSI 模型中如何进行通信?OSI 模型有哪些替代方案? TCP/IP 模型关于专有协议和模型的说明 二、七层模型详解(DNS、CDN、OSI) 状态码DNS nslookup命令 CDN whois命令 …...

QT 中 QProgressDialog 进度条窗口 备查
基础API //两个构造函数 QProgressDialog::QProgressDialog(QWidget *parent nullptr, Qt::WindowFlags f Qt::WindowFlags());QProgressDialog::QProgressDialog(const QString &labelText, const QString &cancelButtonText, int minimum, int maximum, QWidget *…...

学习ShardingSphere前置知识
学习ShardingSphere前置准备知识 一. SPI SPI(Service Provider Interface)是一种Java的扩展机制,用于实现组件之间的松耦合。在SPI模型中,服务提供者(Service Provider)定义了一组接口,而服务…...

读书笔记-《数据结构与算法》-摘要3[选择排序]
选择排序 核心:不断地选择剩余元素中的最小者。 找到数组中最小元素并将其和数组第一个元素交换位置。在剩下的元素中找到最小元素并将其与数组第二个元素交换,直至整个数组排序。 性质: 比较次数(N-1)(N-2)(N-3)…21~N^2/2交换次数N运行…...
Arduino驱动MLX90614红外测温传感器(温湿度传感器)
目录 1、传感器特性 2、测量方法 3、硬件原理图 4、控制器和传感器连线图...
Ubuntu上传文件到SMB共享文件夹
0. 前言 公司有一些数据共享文件夹,平时可以把开发的重要文件放到上面备份。本人开发使用ubuntu系统,共享文件夹是windows的形式,想通过命令的方式,方便快捷,还可shell脚本自动化。 1. 安装挂载库 sudo apt-get upd…...

【Linux】基础IO--重定向理解Linux下一切皆文件缓冲区
文章目录 一、重定向1.什么是重定向2.dup2 系统调用3.理解输入重定向、输出重定向和追加重定向4.简易shell完整实现 二、理解linux下一切皆文件三、缓冲区1.为什么要有缓冲区2.缓冲区的刷新策略3.缓冲区的位置4.实现一个简易的C语言缓冲区5.内核缓冲区 一、重定向 1.什么是重定…...
RINEX介绍
一、RINEX是什么 Receiver Independent Exchange Format (RINEX) 是一种用于存储、交换和处理全球定位系统 (GPS) 接收机观测数据的标准化文件格式。RINEX 格式由国际电信联盟 (ITU) 和国际GPS服务 (IGS) 组织共同开发和维护。它提供了一种通用的数据格式,使得不同…...

ROS-ROS通信机制-服务通信
文章目录 一、服务通信基本知识二、自定义srv三、C实现四、Python实现 一、服务通信基本知识 服务通信也是ROS中一种极其常用的通信模式,服务通信是基于请求响应模式的,是一种应答机制。也即: 一个节点A向另一个节点B发送请求,B接收处理请求…...

chown和chmod
chown和chmod都是在Linux和Unix系统中用于设置文件和文件夹权限的命令,但它们的功能和用途有所不同。 功能:chown主要用于修改文件或文件夹的所有者和所属组,而chmod则主要用于修改文件或文件夹的读写执行权限。用途:如果想要授权…...

【GPU】linux 安装、卸载 nvidia 显卡驱动、cuda 的官方文档、推荐方式(runfile)
文章目录 1. 显卡驱动1.1. 各版本下载地址1.2. 各版本文档地址1.3. 安装、卸载方式 2. CUDA2.1. 各版本下载地址2.2. 各版本文档地址2.3. 安装、卸载方式2.4. 多版本 CUDA 切换方式 1. 显卡驱动 1.1. 各版本下载地址 https://www.nvidia.com/Download/Find.aspx?langzh-cn 1…...

6页手写笔记总结信号与系统常考知识大题知识点
题型一 判断系统特性题型二 求系统卷积题型三 求三大变换正反变换题型四 求全响应题型五 已知微分方程求系统传递函数题型六 已知系统的传递函数求微分方程题型七 画出系统的零极点图,并判断系统的因果性和稳定性 (笔记适合快速复习,可能会有…...
Qt-QSplitter正确设置比例
简短版本: splitter->setSizes({1000, 2000}); // 这个值至少跟像素值设置的一样大,或者更大,例如x10倍详细版本: setSizes 官方介绍如下: Sets the child widgets’ respective sizes to the values given in the…...

一篇吃透大厂面试题,2024找工作一帆风顺。
🏆作者简介,普修罗双战士,一直追求不断学习和成长,在技术的道路上持续探索和实践。 🏆多年互联网行业从业经验,历任核心研发工程师,项目技术负责人。 🎉欢迎 👍点赞✍评论…...
【1day】用友 U8 Cloud系统TaskTreeQuery接口SQL注入漏洞学习
注:该文章来自作者日常学习笔记,请勿利用文章内的相关技术从事非法测试,如因此产生的一切不良后果与作者无关。 目录 一、漏洞描述 二、影响版本 三、资产测绘 四、漏洞复现...

华为快应用中自定义Slider效果
文章目录 一、前言二、实现代码三、参考链接 一、前言 在华为快应用中官方提供了<slider>控件,但是这个控件的限制比较多,比如滑块无法自定义,所以这里进行下自定义,自己修改样式。 二、实现代码 整体效果如下: 源码如下…...

C语言每日一题(43)旋转链表
力扣 61 旋转链表 题目描述 给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置。 示例 1: 输入:head [1,2,3,4,5], k 2 输出:[4,5,1,2,3]示例 2: 输入:head [0,1,2], …...
CCF计算机软件能力认证考试—202209-1如此编码
题目背景 某次测验后,顿顿老师在黑板上留下了一串数字 23333 便飘然而去。凝望着这个神秘数字,小 P 同学不禁陷入了沉思…… 题目描述 已知某次测验包含 � 道单项选择题,其中第 � 题(1≤�≤&…...

Ubuntu18.04安装Ipopt-3.12.8流程
本文主要介绍在Ubuntu18.04中安装Ipopt库的流程,及过程报错的解决方法,已经有很多关于Ipopt安装的博客,但经过我的测试,很多都失效了,经过探索,找到可流畅的安装Ipopt的方法,总结成本篇博客。 …...

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误
HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误,它们的含义、原因和解决方法都有显著区别。以下是详细对比: 1. HTTP 406 (Not Acceptable) 含义: 客户端请求的内容类型与服务器支持的内容类型不匹…...
云计算——弹性云计算器(ECS)
弹性云服务器:ECS 概述 云计算重构了ICT系统,云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台,包含如下主要概念。 ECS(Elastic Cloud Server):即弹性云服务器,是云计算…...

简易版抽奖活动的设计技术方案
1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...

React第五十七节 Router中RouterProvider使用详解及注意事项
前言 在 React Router v6.4 中,RouterProvider 是一个核心组件,用于提供基于数据路由(data routers)的新型路由方案。 它替代了传统的 <BrowserRouter>,支持更强大的数据加载和操作功能(如 loader 和…...

DAY 47
三、通道注意力 3.1 通道注意力的定义 # 新增:通道注意力模块(SE模块) class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...
生成 Git SSH 证书
🔑 1. 生成 SSH 密钥对 在终端(Windows 使用 Git Bash,Mac/Linux 使用 Terminal)执行命令: ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" 参数说明: -t rsa&#x…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1
每日一言 生活的美好,总是藏在那些你咬牙坚持的日子里。 硬件:OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写,"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...

12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...
工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配
AI3D视觉的工业赋能者 迁移科技成立于2017年,作为行业领先的3D工业相机及视觉系统供应商,累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成,通过稳定、易用、高回报的AI3D视觉系统,为汽车、新能源、金属制造等行…...
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要: 近期,在使用较新版本的OpenSSH客户端连接老旧SSH服务器时,会遇到 "no matching key exchange method found", "n…...