当前位置: 首页 > article >正文

1.2 学习驱动(Driver)分为几步?

文章目录

  • 前言
  • 一、什么是UVM中的驱动(Driver)?
  • 二、如何理解Driver?
  • 三、如何使用Driver?
    • 第一步:定义Driver类
    • 第二步:实现run_phase任务
    • 第三步:实现驱动任务
    • 第四步:实例化和配置Driver
  • 四、示例代码分析
  • 五、总结


前言

先从概念入手,解释清楚Driver的作用和它在整个UVM验证平台中的位置。这个应该不难,Driver是UVM中很核心的一个组件,它的主要职责就是把事务(transaction)转换成信号(signal-level),然后驱动到DUT上。这个过程其实就像是一个“翻译器”,把高层次的事务翻译成DUT能理解的信号。嗯,这个比喻应该能帮助用户更好地理解Driver的作用。
接下来,得考虑怎么把Driver的使用步骤讲清楚。创建Driver类其实就是一个继承和注册的过程,继承自uvm_driver,然后用uvm_component_utils宏注册类。这个步骤应该比较直观。
然后是实例化Driver,这个步骤通常是在Agent的build_phase中完成的。嗯,这里我得强调一下,实例化Driver的时候,需要根据Agent的模式(active或passive)来决定是否实例化Driver。如果是active模式,就需要实例化Driver和Sequencer;如果是passive模式,就只需要实例化Monitor。这个逻辑很重要。
配置Driver也是一个关键步骤,这里需要用到uvm_config_db来设置虚拟接口。这个步骤可能会有点抽象。
最后是运行Driver,这个步骤主要是在run_phase中完成的。Driver会通过get_next_item从Sequencer获取事务,然后通过drive_transaction把事务驱动到DUT上。嗯,这个过程其实就是Driver的核心功能。


一、什么是UVM中的驱动(Driver)?

定义
UVM中的Driver是一个关键组件,用于将事务(transaction)转换为实际的信号(signal-level)并驱动到被验证模块(DUT)上。Driver继承自uvm_driver类,并且通常需要通过参数化指定事务类型。
作用

  • 事务转换:将从sequencer获取的事务(transaction)转换为具体的信号,驱动到DUT的接口上。
  • 与Sequencer通信:通过TLM(Transaction Level Modeling)端口与sequencer进行通信,获取事务并发送响应。
  • 时序控制:负责按照DUT的接口协议和时序要求,精确地驱动信号。

二、如何理解Driver?

Driver可以类比为一个“翻译器”和“执行者”:

  • 翻译器:将高层的事务(transaction)翻译为具体的信号(signal-level)。
  • 执行者:按照DUT的接口协议和时序要求,将信号驱动到DUT上。

三、如何使用Driver?

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

第一步:定义Driver类

Driver类需要继承自uvm_driver,并指定它处理的事务类型。例如:

class my_driver extends uvm_driver #(my_transaction);`uvm_component_utils(my_driver)  // 注册组件// 其他成员变量和方法
endclass
  • my_transaction 是事务对象的类型,定义了事务的结构。
  • uvm_component_utils 宏用于将Driver类注册到UVM工厂,方便后续的实例化。

第二步:实现run_phase任务

run_phase是Driver的主要执行阶段。在这个阶段,Driver从序列器获取事务,并调用驱动任务来处理这些事务。

virtual task run_phase(uvm_phase phase);my_transaction req;forever beginseq_item_port.get_next_item(req);  // 从序列器获取事务drive_item(req);  // 驱动事务到DUTseq_item_port.item_done();  // 通知序列器事务已完成end
endtask

第三步:实现驱动任务

驱动任务(如drive_item)负责将事务对象的具体内容转换为DUT的信号。

virtual task drive_item(my_transaction item);@(posedge clk);  // 等待时钟边沿// 将事务对象的属性赋值给DUT的信号dut_signal1 <= item.data1;dut_signal2 <= item.data2;// 其他操作
endtask

第四步:实例化和配置Driver

在验证平台中,需要实例化Driver,并将其连接到DUT的接口上。

my_driver drv;
drv = new("drv", parent);
drv.vif = dut_if_instance;  // 将虚拟接口绑定到DUT的实际接口

四、示例代码分析

以下是一个完整的Driver示例代码,我们将逐步分析其作用。

class simple_driver extends uvm_driver #(simple_transfer);virtual dut_if vif;  // 虚拟接口,用于与DUT交互`uvm_component_utils(simple_driver)  // 注册组件function new(string name = "simple_driver", uvm_component parent = null);super.new(name, parent);endfunctionfunction void build_phase(uvm_phase phase);super.build_phase(phase);// 初始化虚拟接口if (!uvm_config_db#(virtual dut_if)::get(this, "", "dut_vif", vif)) begin`uvm_fatal("NO_VIF", "Virtual interface not found")endendfunctionvirtual task run_phase(uvm_phase phase);simple_transfer req;forever beginseq_item_port.get_next_item(req);  // 从序列器获取事务drive_item(req);  // 驱动事务到DUTseq_item_port.item_done();  // 通知序列器事务已完成endendtaskvirtual task drive_item(simple_transfer item);// 将事务转换为DUT的信号@(posedge vif.clk);vif.data <= item.data;vif.addr <= item.addr;vif.write <= item.write;endtask
endclass

代码分析:

这段代码是一个典型的 UVM 驱动器(Driver)的实现。以下是代码的详细解析和解释:

  1. 类定义和继承
class simple_driver extends uvm_driver #(simple_transfer);

uvm_driver:这是 UVM 提供的基类,专门用于实现驱动器。uvm_driver 是一个参数化类,通过 #(simple_transfer) 指定它处理的事务类型为 simple_transfer。
simple_transfer:这是一个用户定义的事务类,通常包含事务的属性,例如数据、地址、操作类型等。

  1. 虚拟接口
virtual dut_if vif;  // 虚拟接口,用于与 DUT 交互

virtual dut_if:dut_if 是一个虚拟接口,通常在 Testbench 中定义。它描述了 DUT 的信号接口。
vif:这个虚拟接口的实例 vif 是驱动器与 DUT 交互的桥梁,用于将事务转换为具体的信号。

  1. 注册组件
`uvm_component_utils(simple_driver)  // 注册组件

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

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

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

  1. build_phase
function void build_phase(uvm_phase phase);super.build_phase(phase);if (!uvm_config_db#(virtual dut_if)::get(this, "", "dut_vif", vif)) begin`uvm_fatal("NO_VIF", "Virtual interface not found")end
endfunction

build_phase:这是 UVM 的一个阶段,用于组件的构建和初始化。
uvm_config_db:这是一个全局的配置数据库,用于在验证平台中传递配置信息。
get 方法:从配置数据库中获取虚拟接口 dut_if 的实例,并将其赋值给 vif。
uvm_fatal:如果未找到虚拟接口,发出致命错误,终止模拟。

  1. run_phase
virtual task run_phase(uvm_phase phase);simple_transfer req;forever beginseq_item_port.get_next_item(req);  // 从序列器获取事务drive_item(req);  // 驱动事务到 DUTseq_item_port.item_done();  // 通知序列器事务已完成end
endtask

run_phase:这是 UVM 的一个主要执行阶段,驱动器的核心逻辑在此任务中实现。
simple_transfer req:定义了一个事务对象 req,用于接收从序列器传递来的事务。
seq_item_port.get_next_item(req):从序列器(sequencer)获取下一个事务,并将其存储在 req 中。
drive_item(req):调用 drive_item 任务,将事务转换为具体的 DUT 信号。
seq_item_port.item_done():通知序列器事务已完成,可以继续发送下一个事务。

  1. drive_item 任务
virtual task drive_item(simple_transfer item);@(posedge vif.clk);vif.data <= item.data;vif.addr <= item.addr;vif.write <= item.write;
endtask

@(posedge vif.clk):等待时钟的正沿,确保信号在时钟边沿驱动。
vif.data <= item.data:将事务对象 item 中的 data 属性赋值给 DUT 的信号 data。
vif.addr <= item.addr:将事务对象 item 中的 addr 属性赋值给 DUT 的信号 addr。
vif.write <= item.write:将事务对象 item 中的 write 属性赋值给 DUT 的信号 write。

这段代码实现了一个简单的 UVM 驱动器,能够从序列器获取事务,将其转换为 DUT 的信号,并按照时钟节拍驱动到 DUT。它是 UVM 验证环境中连接序列器和 DUT 的关键组件,负责将高层次的事务转换为具体的硬件激励。

功能总结

  • 事务转换:从序列器获取事务对象(simple_transfer),将其属性(如 data、addr、write)转换为 DUT 的具体信号。
  • 与序列器通信:通过 seq_item_port 与序列器交互,获取事务并通知事务已完成。
  • 时序控制:使用时钟信号 vif.clk 确保信号在正确的时钟边沿驱动。
  • 虚拟接口的使用:通过虚拟接口 vif 与 DUT 交互,确保驱动器能够访问 DUT 的信号。
  • 错误处理:如果未找到虚拟接口,使用 uvm_fatal 报错并终止模拟。

五、总结

Driver是UVM验证环境中非常重要的组件,它负责将事务对象转换为DUT可以理解的信号。使用Driver需要以下步骤:

  1. 定义Driver类,继承自uvm_driver并指定事务类型。
  2. 实现run_phase任务,从序列器获取事务并调用驱动任务。
  3. 实现驱动任务,将事务对象的属性转换为DUT的信号。
  4. 在验证平台中实例化和配置Driver。

相关文章:

1.2 学习驱动(Driver)分为几步?

文章目录 前言一、什么是UVM中的驱动&#xff08;Driver&#xff09;&#xff1f;二、如何理解Driver&#xff1f;三、如何使用Driver&#xff1f;第一步&#xff1a;定义Driver类第二步&#xff1a;实现run_phase任务第三步&#xff1a;实现驱动任务第四步&#xff1a;实例化和…...

【MySQL篇】事务的认识以及四大特性

何为事务&#xff1f; 事务&#xff08;Transaction&#xff09;是指一组操作的集合&#xff0c;这些操作要么全部执行成功&#xff0c;要么全部不执行。事务通常用于保证数据库的一致性、完整性和可靠性&#xff0c;确保数据的完整性与正确性。 有效避免部分执行&#xff0c…...

2.7日学习总结

深入探究栈、队列与二叉树 一、栈的深度剖析 进阶特性&#xff1a;除了常规的入栈、出栈操作&#xff0c;栈在处理函数调用、表达式求值等场景时&#xff0c;展现出独特的递归模拟能力。利用栈可以将递归算法转化为非递归形式&#xff0c;有效避免因递归过深导致的栈溢出问题。…...

SQL带外注入

SQL 带外注入&#xff08;Out-of-Band SQL Injection, OOB SQLi&#xff09; 是 SQL 注入的一种特殊类型&#xff0c;主要用于以下情况&#xff1a; 数据库没有直接返回错误信息&#xff08;比如被防火墙拦截了&#xff09;。无法使用常规注入手法&#xff08;如 UNION、错误信…...

Nginx进阶篇 - nginx多进程架构详解

文章目录 1. nginx的应用特点2. nginx多进程架构2.1 nginx多进程模型2.2 master进程的作用2.3 进程控制2.4 worker进程的作用2.5 worker进程处理请求的过程2.6 nginx处理网络事件 1. nginx的应用特点 Nginx是互联网企业使用最为广泛的轻量级高性能Web服务器&#xff0c;其特点是…...

【算法专场】分治(下)

目录 前言 归并排序 思想 912. 排序数组 算法思路 算法代码 LCR 170. 交易逆序对的总数 算法思路 算法代码 315. 计算右侧小于当前元素的个数 - 力扣&#xff08;LeetCode&#xff09; 算法思路 算法代码 493. 翻转对 算法思路 算法代码 好久不见~时隔多日&…...

OSPF基础(2):数据包详解

OSPF数据包(可抓包) OSPF报文直接封装在IP报文中&#xff0c;协议号89 头部数据包内容&#xff1a; 版本(Version):对于OSPFv2&#xff0c;该字段值恒为2(使用在IPV4中)&#xff1b;对于OSPFv3&#xff0c;该字段值恒为3(使用在IPV6中)。类型(Message Type):该OSPF报文的类型。…...

ubuntu直接运行arm环境qemu-arm-static

qemu-arm-static 嵌入式开发有时会在ARM设备上使用ubuntu文件系统。开发者常常会面临这样一个问题&#xff0c;想预先交叉编译并安装一些应用程序&#xff0c;但是交叉编译的环境配置以及依赖包的安装十分繁琐&#xff0c;并且容易出错。想直接在目标板上进行编译和安装&#x…...

Docker Desktop安装kubernetes时一直在Starting:Kubernetes failed to start

原因&#xff1a;由于墙的问题&#xff0c;导致拉取国外的K8s镜像失败 解决&#xff1a; 下载 k8s-for-docker-desktop 选中自己的kubernetes 版本 下载zip包 PowerShell运行load_images.ps1文件 重启docker kubernetes运行成功...

beyond the ‘PHYSICAL‘ memory limit.问题处理

Container [pid5616,containerIDcontainer_e50_1734408743176_3027740_01_000006] is running 507887616B beyond the ‘PHYSICAL’ memory limit. Current usage: 4.5 GB of 4 GB physical memory used; 6.6 GB of 8.4 GB virtual memory used. Killing container. 1.增大map…...

AI大模型零基础学习(1):大模型使用篇

一、大模型是什么&#xff1f;为什么你需要它&#xff1f; 一句话理解&#xff1a;大模型像一个能听懂人话的"超级智能助手"&#xff0c;它能写文章、解数学题、翻译语言、写代码…只要你会打字提问&#xff0c;它就能给出答案。 典型场景&#xff1a; 学生党&…...

StarSpider 星蛛 爬虫 Java框架 可以实现 lazy爬取 实现 HTML 文件的编译,子标签缓存等操作

StarSpider 星蛛 爬虫 Java框架 开源技术栏 StarSpider 能够实现 针对 HTML XSS SQL 数学表达式等杂乱数据的 爬取 解析 提取 需求&#xff01; 目录 文章目录 StarSpider 星蛛 爬虫 Java框架目录介绍如何获取&#xff1f;maven配置 架构是什么样的&#xff1f;结果对象的类…...

【翻译+论文阅读】DeepSeek-R1评测:粉碎GPT-4和Claude 3.5的开源AI革命

目录 一、DeepSeek-R1 势不可挡二、DeepSeek-R1 卓越之处三、DeepSeek-R1 创新设计四、DeepSeek-R1 进化之路1. 强化学习RL代替监督微调学习SFL2. Aha Moment “啊哈”时刻3. 蒸馏版本仅采用SFT4. 未来研究计划 部分内容有拓展&#xff0c;部分内容有删除&#xff0c;与原文会有…...

先进制造aps专题二十八 生产排程仿真引擎和工厂生产仿真引擎的设计

一 排产仿真引擎的设计 主要分为仿真模型&#xff0c;仿真模型逻辑和仿真框架这三个部分 1 仿真模型 和算法排产不一样&#xff0c;在算法排产里&#xff0c;机器对应的是数据库记录&#xff0c;排产逻辑是写在整体的算法里的&#xff0c;而仿真排产&#xff0c;机器对应的是…...

WPF模板

WPF模板深度解析&#xff1a;打造个性化UI的利器 在WPF&#xff08;Windows Presentation Foundation&#xff09;的世界里&#xff0c;模板&#xff08;Template&#xff09;是构建个性化用户界面&#xff08;UI&#xff09;不可或缺的工具。它们允许开发者将控件的逻辑功能与…...

动态规划LeetCode-121.买卖股票的最佳时机1

给定一个数组 prices &#xff0c;它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票&#xff0c;并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。 返回你可以从这笔交易中获取的最大利润。…...

pytest+request+yaml+allure 接口自动化测试全解析[手动写的跟AI的对比]

我手动写的:Python3:pytest+request+yaml+allure接口自动化测试_request+pytest+yaml-CSDN博客 AI写的:pytest+request+yaml+allure 接口自动化测试全解析 在当今的软件开发流程中,接口自动化测试扮演着至关重要的角色。它不仅能够提高测试效率,确保接口的稳定性和正确性…...

单片机通讯中的时序图:初学者的入门指南

一、什么是时序图&#xff1f; 在单片机的世界里&#xff0c;时序图是一种非常重要的工具&#xff0c;它用于描述信号在时间上的变化规律。简单来说&#xff0c;时序图就像是信号的“时间线”&#xff0c;它展示了各个信号线在不同时间点上的电平状态。通过时序图&#xff0c;我…...

#渗透测试#批量漏洞挖掘#微商城系统 goods SQL注入漏洞

免责声明 本教程仅为合法的教学目的而准备&#xff0c;严禁用于任何形式的违法犯罪活动及其他商业行为&#xff0c;在使用本教程前&#xff0c;您应确保该行为符合当地的法律法规&#xff0c;继续阅读即表示您需自行承担所有操作的后果&#xff0c;如有异议&#xff0c;请立即停…...

Lua中文语言编程源码-第十一节,其它小改动汉化过程

__tostring 汉化过程 liolib.c metameth[] {"__转换为字符串", f_tostring}, lauxlib.c luaL_callmeta(L, idx, "__转换为字符串") lua.c luaL_callmeta(L, 1, "__转换为字符串") __len 汉化过程 ltm.c luaT_eventname[] ltablib.c c…...

import { Component, Vue, Prop, Watch } from ‘vue-property-decorator‘

文章目录 导入部分的解释总结Vue 3 的推荐替代方案总结 你提供的代码片段是使用 vue-property-decorator 库的示例&#xff0c;这是一个第三方库&#xff0c;它提供了 Vue 组件的装饰器&#xff0c;使得编写类风格的 Vue 组件更加方便。以下是对代码中每个部分的详细解释&…...

C++基础系列【5】namespace using

本文主要介绍namespace和using。 什么是namespace&#xff1f; namespace是指命名空间&#xff0c;表示某个变量标识符的可见空间&#xff0c;比如下面的代码&#xff1a; namespace Meow {int k 100; }int main() {std::cout << k << std::endl; }这段代码中在…...

MySQL万能备份脚本

此脚本适用于 MySQL 各个生命周期的版本 #!/bin/bash # mybackup.sh# 备份保留天数&#xff0c;建议保留三天 days7 # 备份时间 time$(date %Y%m%d%H%M%S) # 备份保存路径 backup_dir/opt/backup # 备份工具 toolmysqldump # 端口 port"3306" # 是否采用 --all-data…...

分桶函数的使用

除了 NTILE 函数&#xff0c;SQL 中还有其他一些与 分桶&#xff08;bucketization&#xff09;相关的函数&#xff0c;虽然它们的实现方式不同&#xff0c;但都涉及将数据分成多个区间或组。以下是一些常用的分桶函数&#xff1a; 1. CASE 语句 虽然 CASE 不是开窗函数&…...

5. k8s二进制集群之ETCD集群部署

下载etcd安装包创建etcd配置文件准备证书文件和etcd存储目录ETCD证书文件安装(分别对应指定节点)创建证书服务的配置文件启动etcd集群验证etcd集群状态继续上一篇文章《k8s二进制集群之ETCD集群证书生成》下面介绍一下etcd证书生成配置。 下载etcd安装包 https://github.com…...

JMeter通过BeanShell写入CSV文件中的中文乱码

在 JMeter 中通过 BeanShell 写入 CSV 文件时&#xff0c;如果出现中文乱码问题&#xff0c;通常是因为文件编码不匹配。默认情况下&#xff0c;FileWriter 使用的是系统默认编码&#xff08;可能是 ISO-8859-1 或其他非 UTF-8 编码&#xff09;&#xff0c;而中文字符需要 UTF…...

智能化转型2.0:从“工具应用”到“价值重构”

过去几年&#xff0c;“智能化”从一个模糊的概念逐渐成为企业发展的核心议题。2024年&#xff0c;随着生成式AI、大模型、智能体等技术的爆发式落地&#xff0c;中国企业正式迈入智能化转型的2.0时代。这一阶段的核心特征是从单一场景的“工具应用”转向全链条的“价值重构”&…...

X Window System 架构概述

X Window System 架构概述 1. X Server 与 X Client ​ 这里引入一张维基百科的图&#xff0c;在Linux系统中&#xff0c;若用户需要图形化界面&#xff0c;则可以使用X Window System&#xff0c;其使用**Client-Server**架构&#xff0c;并通过网络传输相关信息。 ​ ​ X…...

【ArcGIS Pro 简介1】

ArcGIS Pro 是由 Esri &#xff08;Environmental Systems Research Institute&#xff09;公司开发的下一代桌面地理信息系统&#xff08;GIS&#xff09;软件&#xff0c;是传统 ArcMap 的现代化替代产品。它结合了强大的空间分析能力、直观的用户界面和先进的三维可视化技术…...

启明星辰发布MAF大模型应用防火墙产品,提升DeepSeek类企业用户安全

2月7日&#xff0c;启明星辰面向DeepSeek等企业级大模型业务服务者提供的安全防护产品——天清MAF&#xff08;Model Application Firewall&#xff09;大模型应用防火墙产品正式发布。 一个新赛道将被开启…… DeepSeek的低成本引爆赛道规模 随着DeepSeek成为当前最热的现象级…...