1.1 学习代理(Agent)分为几步?

server/2025/2/7 17:54:06/

文章目录

  • 前言
  • 一、什么是UVM中的代理(Agent)
  • 二、如何理解Agent
  • 三、如何使用Agent
    • 1、创建Agent类
    • 2、实例化组件
    • 3、配置Agent
    • 4、连接组件
  • 四、示例代码分析


前言

从Agent的概念入手,这个应该比较容易解释,就是把Driver、Monitor和Sequencer封装在一起,这样能让验证环境更清晰。
然后,我得考虑怎么解释Agent的使用步骤。这个需要我好好梳理一下,从创建Agent类开始,到实例化组件,再到配置Agent,最后是连接组件,这些步骤得一步一步地讲清楚。


UVM(Universal Verification Methodology)中的代理(Agent)是一个关键组件,用于封装与特定协议相关的驱动程序(Driver)、监视器(Monitor)和序列发生器(Sequencer)。以下是对UVM中代理的详细解释、使用方法以及示例代码的分析:

一、什么是UVM中的代理(Agent)

定义:

  • Agent是UVM中的一个组件,用于封装与特定协议相关的驱动程序、监视器和序列发生器。
  • 它继承自uvm_component,并且可以是主动的(UVM_ACTIVE)或被动的(UVM_PASSIVE)。
    作用:
  • 封装性:将与特定协议相关的组件封装在一起,提高代码的可重用性和可维护性。
  • 协议处理:处理特定协议的数据发送、驱动和采样。
  • 灵活配置:可以根据测试需求灵活配置Agent的行为,例如设置为active或passive模式。

二、如何理解Agent

  • 组件封装Agent将Driver、Monitor和Sequencer封装在一起,形成一个独立的模块
  • 主动与被动模式:
    • 主动模式(UVM_ACTIVE):Agent会实例化Driver和Sequencer,用于生成激励并驱动到DUT(Device Under Test)。
    • 被动模式(UVM_PASSIVE):Agent只实例化Monitor,用于监视DUT的输出。

层次结构:在复杂的验证环境中,不同的接口协议可以分成不同的Agent,便于环境的管理和规范化。

三、如何使用Agent

使用Agent通常需要以下步骤:

  1. 创建Agent类:继承自uvm_agent,并定义内部组件(Driver、Monitor、Sequencer)。
  2. 实例化组件:在build_phase中实例化Driver、Monitor和Sequencer。
  3. 配置Agent:设置Agent的模式(active或passive),并通过uvm_config_db进行参数配置。
  4. 连接组件:在connect_phase中连接Driver和Sequencer的端口。

1、创建Agent类

  1. 继承uvm_agent:创建一个继承自uvm_agent的类,并定义内部组件(Driver、Monitor、Sequencer)。
  2. 注册类:使用uvm_component_utils宏进行类的注册,以便UVM工厂可以实例化它。
  3. 定义组件:在类中声明Driver、Monitor和Sequencer的实例。

示例代码

class my_agent extends uvm_agent;my_driver drv;          // 驱动程序my_monitor mon;         // 监视器my_sequencer sqr;       // 序列发生器`uvm_component_utils(my_agent)  // 注册类function new(string name = "my_agent", uvm_component parent = null);super.new(name, parent);endfunctionvirtual function void build_phase(uvm_phase phase);super.build_phase(phase);// 实例化监视器mon = my_monitor::type_id::create("mon", this);// 根据配置决定是否实例化驱动程序和序列发生器if (is_active == UVM_ACTIVE) begindrv = my_driver::type_id::create("drv", this);sqr = my_sequencer::type_id::create("sqr", this);endendfunctionvirtual function void connect_phase(uvm_phase phase);super.connect_phase(phase);// 如果是主动模式,连接驱动程序和序列发生器if (is_active == UVM_ACTIVE) begindrv.seq_item_port.connect(sqr.seq_item_export);endendfunction
endclass

2、实例化组件

在build_phase中,根据Agent的模式(active或passive)实例化组件:

  • 被动模式(passive):只实例化Monitor。
  • 主动模式(active):实例化Driver、Monitor和Sequencer。

示例代码

virtual function void build_phase(uvm_phase phase);super.build_phase(phase);// 实例化监视器mon = my_monitor::type_id::create("mon", this);// 根据配置决定是否实例化驱动程序和序列发生器if (is_active == UVM_ACTIVE) begindrv = my_driver::type_id::create("drv", this);sqr = my_sequencer::type_id::create("sqr", this);end
endfunction

3、配置Agent

  1. 设置Agent模式:通过is_active属性设置Agent为UVM_ACTIVE或UVM_PASSIVE。
  2. 配置参数:通过uvm_config_db设置Agent的其他参数,例如接口句柄、配置对象等。

示例代码
在测试环境中配置Agent:

class my_test extends uvm_test;my_agent agt;`uvm_component_utils(my_test)function new(string name = "my_test", uvm_component parent = null);super.new(name, parent);endfunctionvirtual function void build_phase(uvm_phase phase);super.build_phase(phase);// 实例化Agentagt = my_agent::type_id::create("agt", this);// 配置Agent为active模式agt.is_active = UVM_ACTIVE;// 通过uvm_config_db设置接口句柄(假设接口名为vif)uvm_config_db#(my_interface)::set(this, "agt", "vif", vif);endfunction
endclass

4、连接组件

在connect_phase中,连接Driver和Sequencer的端口,以便它们可以通信。
示例代码

virtual function void connect_phase(uvm_phase phase);super.connect_phase(phase);// 如果是主动模式,连接驱动程序和序列发生器if (is_active == UVM_ACTIVE) begindrv.seq_item_port.connect(sqr.seq_item_export);end
endfunction

以下是使用Agent的完整步骤:

  1. 创建Agent类:
  • 继承uvm_agent。
  • 定义内部组件(Driver、Monitor、Sequencer)。
  • 使用uvm_component_utils宏注册类。
  1. 实例化组件:
  • 在build_phase中,根据is_active属性实例化组件。
  1. 配置Agent:
  • 设置is_active属性。
  • 通过uvm_config_db设置其他参数。
  1. 连接组件:
  • 在connect_phase中,连接Driver和Sequencer的端口。

通过以上步骤,你可以构建一个完整的Agent,并将其集成到验证环境中。

四、示例代码分析

以下是一个简单的Agent示例代码及其分析:

示例代码

class my_agent extends uvm_agent;// 1. 定义内部组件my_driver drv;          // 驱动程序my_monitor mon;         // 监视器my_sequencer sqr;       // 序列发生器// 2. 注册类`uvm_component_utils(my_agent)// 3. 构造函数function new(string name = "my_agent", uvm_component parent = null);super.new(name, parent);endfunction// 4. build_phasevirtual function void build_phase(uvm_phase phase);super.build_phase(phase);// 实例化监视器mon = my_monitor::type_id::create("mon", this);// 根据配置决定是否实例化驱动程序和序列发生器if (is_active == UVM_ACTIVE) begindrv = my_driver::type_id::create("drv", this);sqr = my_sequencer::type_id::create("sqr", this);endendfunction// 5. connect_phasevirtual function void connect_phase(uvm_phase phase);super.connect_phase(phase);// 如果是主动模式,连接驱动程序和序列发生器if (is_active == UVM_ACTIVE) begindrv.seq_item_port.connect(sqr.seq_item_export);endendfunction
endclass

这段代码定义了一个 UVM 代理(uvm_agent)类 my_agent,它是 UVM 验证平台中的一个关键组件。以下是代码的详细解析和功能说明:

  1. 类定义和继承
class my_agent extends uvm_agent;

uvm_agent:这是 UVM 提供的基类,用于实现验证平台中的代理组件。代理组件通常包含驱动器(Driver)、监视器(Monitor)和序列发生器(Sequencer)。
my_agent:这是用户定义的代理类,继承自 uvm_agent。

  1. 定义内部组件
my_driver drv;          // 驱动程序
my_monitor mon;         // 监视器
my_sequencer sqr;       // 序列发生器

my_driver:驱动程序,负责将事务转换为具体的信号并驱动到 DUT。
my_monitor:监视器,负责监视 DUT 的信号并生成事务。
my_sequencer:序列发生器,负责生成事务并将其传递给驱动程序。

  1. 注册类
`uvm_component_utils(my_agent)

uvm_component_utils:这是 UVM 提供的一个宏,用于将组件注册到 UVM 工厂中。注册后,可以通过名字创建和配置该组件。
my_agent:将 my_agent 类注册到 UVM 工厂中,方便后续实例化和使用。

  1. 构造函数
function new(string name = "my_agent", uvm_component parent = null);super.new(name, parent);
endfunction

new:这是类的构造函数,用于初始化 my_agent 实例。
super.new:调用父类 uvm_agent 的构造函数,完成初始化。

  1. build_phase
virtual function void build_phase(uvm_phase phase);super.build_phase(phase);// 实例化监视器mon = my_monitor::type_id::create("mon", this);// 根据配置决定是否实例化驱动程序和序列发生器if (is_active == UVM_ACTIVE) begindrv = my_driver::type_id::create("drv", this);sqr = my_sequencer::type_id::create("sqr", this);end
endfunction

build_phase:这是 UVM 的一个阶段,用于组件的构建和初始化。
super.build_phase:调用父类的 build_phase 方法,完成父类的初始化。

  • 实例化监视器:
mon = my_monitor::type_id::create("mon", this);

a.使用 type_id::create 方法实例化监视器 mon。
b.this 表示当前组件的父组件。

  • 根据配置决定是否实例化驱动程序和序列发生器:
if (is_active == UVM_ACTIVE) begindrv = my_driver::type_id::create("drv", this);sqr = my_sequencer::type_id::create("sqr", this);
end

a.is_active:这是一个 UVM 提供的属性,用于决定代理是主动模式(UVM_ACTIVE)还是被动模式(UVM_PASSIVE)。
b.UVM_ACTIVE:如果代理是主动模式,实例化驱动程序 drv 和序列发生器 sqr。
c.UVM_PASSIVE:如果代理是被动模式,不实例化驱动程序和序列发生器,只实例化监视器。

  1. connect_phase
virtual function void connect_phase(uvm_phase phase);super.connect_phase(phase);// 如果是主动模式,连接驱动程序和序列发生器if (is_active == UVM_ACTIVE) begindrv.seq_item_port.connect(sqr.seq_item_export);end
endfunction

connect_phase:这是 UVM 的一个阶段,用于组件之间的连接。
super.connect_phase:调用父类的 connect_phase 方法,完成父类的连接。

  • 连接驱动程序和序列发生器:
if (is_active == UVM_ACTIVE) begindrv.seq_item_port.connect(sqr.seq_item_export);
end

a.drv.seq_item_port:驱动程序的 TLM 端口,用于接收事务。
b.sqr.seq_item_export:序列发生器的 TLM 导出,用于发送事务。
c.connect:将驱动程序的 TLM 端口连接到序列发生器的 TLM 导出,确保事务可以从序列发生器传递到驱动程序。

这段代码实现了一个 UVM 代理 my_agent,它可以根据配置决定是否实例化驱动程序和序列发生器,并将它们连接起来。代理是 UVM 验证平台中的关键组件,负责管理驱动程序、监视器和序列发生器之间的交互。通过灵活的配置和连接,代理可以适应不同的验证需求,提高验证平台的可重用性和可维护性。

功能总结

  • 组件实例化:实例化监视器 mon,用于监视 DUT 的信号并生成事务。根据配置决定是否实例化驱动程序 drv 和序列发生器 sqr。
  • 组件连接:如果代理是主动模式,将驱动程序的 TLM 端口连接到序列发生器的 TLM 导出,确保事务可以从序列发生器传递到驱动程序。
  • 灵活性:通过 is_active 属性,代理可以配置为主动模式或被动模式,灵活适应不同的验证需求。
  • UVM 工厂注册:使用 uvm_component_utils 宏将 my_agent 类注册到 UVM 工厂,方便后续实例化和使用。

http://www.ppmy.cn/server/165727.html

相关文章

MS SQL Server partition by 函数实战二 编排考场人员

目录 需求 输出效果 范例运行环境 表及视图样本设计 功能实现 生成考场数据 生成重复的SQL语句 封装为统计视图 编写存储过程实现统计 小结 需求 假设有若干已分配准考证号的考生,准考证号示例(01010001)共计8位,前4位…

【C++】B2115 密码翻译

博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 💯前言💯题目解析💯1. 老师的做法代码实现:思路解析: 💯2. 我的做法代码实现:思路分析: 💯3. 老师…

Linux权限大揭秘:深入理解系统安全

W...Y的主页 😊 代码仓库分享💕 🍔前言: 在之前的内容中,我们了解了Linux中的一些简单权限,如root超级账号与普通账户的区别、Linux文件权限管理、文件类型和访问权限以及许多关于修改权限的指令及其规则…

深入解析 Chrome 浏览器的多进程架构:标签页是进程还是线程?(中英双语)

深入解析 Chrome 浏览器的多进程架构:标签页是进程还是线程? 1. 引言 Google Chrome 作为全球最流行的浏览器之一,以其稳定性、安全性和多任务处理能力而闻名。而其高效的表现,很大程度上归功于其独特的多进程架构(M…

一篇关于高等数理统计结合机器学习论文的撰写(如何撰写?)

前言 在大学或者研究生阶段,大家可能都会遇到一个问题就是,在上高等数理统计课程时,老师总会让同学们写一些大作业,比如论文什么的,接下来我会从计算机领域的角度,带领大家开启一篇从0到1的高等数理统计文…

在Ubuntu上使用Docker部署DeepSeek

在Ubuntu上使用Docker部署DeepSeek,并确保其可以访问公网网址进行对话,可以按照以下步骤进行: 一、安装Docker 更新Ubuntu的软件包索引: sudo apt-get update安装必要的软件包,这些软件包允许apt通过HTTPS使用存储库…

Mac M1 源码安装FFmpeg,开启enable-gpl 和 lib x264

1、第一步:下载并安装minicoda curl -O https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-arm64.shsh Miniconda3-latest-MacOSX-arm64.sh2、第二步:安装必要的依赖 conda install -c conda-forge gcc make nasm yasm3、第三步&#xff…

LeetCode Java面试刷题笔记汇总

LeetCode Java刷题笔记汇总,按照类型刷题效率更高。刷题前需要先学习数据结构与算法的基础知识:Java 数据结构与算法。 大厂面试算法题有一定的运气成分,有可能你刷的比较少,但是遇到会的题就进去了,也有可能你刷的比…