基于UVM搭验证环境

news2025/2/11 9:20:12

基于UVM搭验证环境基本思路:

       首先,我们搭建环境时一般都有一个目标的DUT。此时,我们可以结合所要验证的的模块、是否需要VIP、验证侧重点等在典型的UVM验证环境的基础上做适当调整后形成一个大体的环境架构。比如,需要一个ahb_vip_agent、系统级还是模块级的DUT等等。这样,整个验证环境中需要几个in_agent、是否需要out_agent、reference model是否需要自己写就比较清楚了。基于这些考虑,我们的环境架构基本上就定下来了。

       其次,当整个环境的架构确定好了之后,接下来就是具体的编写环境组件的过程了。这个是整个环境搭建最重要和工作量最大的部分。有的喜欢自上而下地先写顶层,env再agent,driver,transaction来编写各个组件;有的习惯自下而上地先写好每个driver,monitor再在agent或env中做组合连接。我的经验是,在搭建环境的过程中,认知就是一个从框架到编码的过程,所以自上而下的方式更符合这样一个认知的过程。另外,在真正工作中,我还是觉得我们搭建环境的第一步不要想着一次性把环境中所有的组件都写完,而是先写完除scoreboard和reference model之外的所有规划组件。至于testcase,可以先写好冒烟case(当然可能包括冒烟case需要的sequence)。这样做的目的是我们可以在最短的时间里调试环境并能够正常冒烟。之后再根据项目进度逐步添加reference model,scoreboard,sequence和case等,并不断完善。

基于UVM搭建验证环境的过程:

①编写uvm_env。首先根据确定的环境架构,编写env将整个环境的结构关系确定下来。

②如果环境中要用到vip,可以在env中把vip包进来。

③环境中可能会包含多个agent。其实agent可以理解为一个单一的env。所以还是从agent自顶向下的去编写,agent→interface→sequencer、sequence→driver→moitor。

④在编写agent的driver过程中可能需要同步进行transaction的编写。这样可以不断地调整transaction中的配置变量。

⑤编写top.sv。完成env和agent之后,环境的interface基本也确定下来了。这个时候可以编写顶层信号连接。

⑥编写base_test.sv。这个过程中可以同步编写顶层的transaction以及顶层的一些sequence和sequencer。

⑦待上述编写完成后,开始编写环境和代码的filelist以及仿真脚本。调试冒烟case。

以上7个小点是一个基本的环境搭建步骤。这个环境可以完成待测代码的冒烟测试。之后的工作,就是在这个环境的基础上补充reference model和scoreboard的功能,以及根据验证计划不断补充激励并完成验证工作。

《uvm实战》温习小记:

set与get函数的参数:

config_db机制用于uvm验证平台间传递参数(如int,virtual interface),set与get通常是成对出现的,set函数是寄信,get函数是收信,通常习惯在最顶层处(tb_top)处set,使用方式如下:

uvm_config_db# (int) : : set (this, "env.i_agt.drv" , "pre_num" , 100);

其中第一个参数和第二个参数组合起来组成寄信的目标路径,因此上面也可以改成

uvm_config_db# (int) : : set (this.env, "i_agt.drv" , "pre_num" , 100);(一般不用)

与此路径符合的才能收信,其中第一个参数必须是uvm_component实例的指针,第二个参数是相对于实例的路径。第三个参数表示一个记号,用于说明这个值是传给目标中的哪个成员的,第四个参数是要设置的值。

需要注意的是如果在顶层tb_top中set,用法为

uvm_config_db# (int) : : set (null, "uvm_test_top.env.i_agt.drv" , "pre_num" , 100);

set函数原型

static function void set(
  uvm_component context,  // 上下文(作用域)
  string inst_name,        // 目标实例的路径(支持通配符)
  string field_name,       // 配置项的名称(字符串)
  T value                  // 要设置的配置值(任意类型)
);

  1. context

    • 作用:定义配置的作用域(通常是一个组件的指针)。

    • 规则

      • 如果 context 设置为 null,配置将全局可见。

      • 如果 context 设置为某个组件(如 this),配置的作用域将限定在该组件的层次结构下。

      • 子组件可以通过向上查找父组件的作用域来访问配置

  2. inst_name

    • 作用:指定目标实例的路径(支持通配符 * 或 .*)。

    • 示例

      • "uvm_test_top.env.agent": 精确匹配路径。

      • "uvm_test_top.env.*": 匹配 env 下所有组件。

      • "*.agent": 匹配所有名为 agent 的实例。

  3. field_name

    • 作用:配置项的唯一标识符(字符串),需与 get() 中的名称一致。

    • 示例"vif""cfg""num_packets"

  4. value

    • 作用:要传递的值,可以是任意类型(如接口、对象、整数等)。

    • 示例:传递虚拟接口、配置对象、字符串等。

收信一般在组件中的build_phase收信,以driver为例,使用方式如下:

uvm_config_db# (int) : : get (this, "" , "pre_num" , p_num);

其中第一个参数和第二个参数用来组成收信地址,第一个也必须是uvm_component实例的指针,第二个参数则是相对于此实例的路径。一般的,如果第一个参数是this,第二个参数可以是一个空的字符串,第三个参数就是set中的参数,必须严格对应,第四个参数则是该实例中要设置的变量。

get函数原型

static function bit get(
  uvm_component context,  // 上下文(作用域)
  string inst_name,        // 当前实例的路径
  string field_name,       // 配置项的名称
  inout T value            // 接收配置值的变量
);

  1. context

    • 作用:与 set() 中的 context 对应,定义查找配置的作用域。

    • 规则

      • 通常设置为 this(当前组件),UVM 会从当前组件向上遍历父组件的作用域查找配置。

      • 如果设置为 null,则从全局作用域查找。

  2. inst_name

    • 作用:当前组件的完整路径名,通常通过 get_full_name() 获取。

    • 自动获取:在组件内部使用时,可以直接用 uvm_root::get().get_full_name() 或 this.get_full_name()

  3. field_name

    • 作用:与 set() 中的 field_name 一致,用于匹配配置项。

  4. value

    • 作用:接收配置值的变量,类型必须与 set() 中传递的类型一致。

    • 注意:如果未找到配置,get() 返回 0,且 value 保持不变。

关键使用场景

1. 传递虚拟接口(Virtual Interface)

// 在顶层模块中设置接口
initial begin
         uvm_config_db#(virtual apb_if)::set(null, "uvm_test_top.env.agent", "vif", apb_if);
end

// 在 Agent 中获取接口
class my_agent extends uvm_agent;
          virtual apb_if vif;
          function void build_phase(uvm_phase phase);
                    if (!uvm_config_db#(virtual apb_if)::get(this, "", "vif", vif)) begin
                              `uvm_fatal("CFGERR", "Failed to get vif!")
                    end
          endfunction
endclass

2. 传递配置对象

// 在测试用例中设置配置对象
class my_test extends uvm_test;
  my_config cfg;
  function void build_phase(uvm_phase phase);
    cfg = my_config::type_id::create("cfg");
    cfg.mode = FAST_MODE;
    uvm_config_db#(my_config)::set(this, "env.agent", "cfg", cfg);
  endfunction
endclass

// 在 Agent 中获取配置对象
class my_agent extends uvm_agent;
  my_config cfg;
  function void build_phase(uvm_phase phase);
    if (!uvm_config_db#(my_config)::get(this, "", "cfg", cfg)) begin
      `uvm_fatal("CFGERR", "Failed to get cfg!")
    end
  endfunction
endclass

注意事项

  1. 作用域匹配

    • set() 和 get() 的 context 和 inst_name 必须匹配,否则无法获取配置。

    • 例如:set(this, "env.agent", ...) 和 get(this, "env.agent", ...)

  2. 通配符的使用

    • 使用 * 或 .* 可以简化路径匹配,但要避免过度使用导致配置冲突。

  3. 类型一致性

    • set() 和 get() 的模板参数(如 uvm_config_db#(int))必须完全一致。

  4. 时序问题

    • set() 应在 get() 之前执行(通常在 build_phase 中设置)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2296244.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

十款开源的论坛建站工具

以下是十款开源的论坛建站工具,它们各具特色,能够满足不同用户的需求: Discuz!(Crossday Discuz! Board) 特点:基础架构采用web编程组合PHPMySQL,用户可以在不需要任何编程的基础上,…

vue学习6

1. 智慧商城 1. 路由设计配置 单个页面&#xff0c;独立展示的&#xff0c;是一级路由 2.二级路由配置 规则&组件配置导航链接配置路由出口 <template><div id"app"><!--二级路由出口--><router-view></router-view><van-…

线程池以及日志、线程总结

一、线程池以及日志 1、基础线程池写法 主线程在main函数中构建一个线程池&#xff0c;初始化(Init)后开始工作(Start) 此时线程池中每个线程都已经工作起来了&#xff0c;只是任务队列中任务为空&#xff0c;所有线程处于休眠状态(通过线程同步中的条件变量实现&#xff0c…

Vue 响应式渲染 - 过滤应用

Vue 渐进式JavaScript 框架 基于Vue2的学习笔记 - Vue响应式渲染综合 - 过滤应用 目录 过滤应用 引入vue Vue设置 设置页面元素 模糊查询过滤实现 函数表达式实现 总结 过滤应用 综合响应式渲染做一个输入框&#xff0c;用来实现&#xff1b;搜索输入框关键词符合列表。…

【ThreeJS Basics 1-3】Hello ThreeJS,实现第一个场景

文章目录 环境创建一个项目安装依赖基础 Web 页面概念解释编写代码运行项目 环境 我的环境是 node version 22 创建一个项目 首先&#xff0c;新建一个空的文件夹&#xff0c;然后 npm init -y , 此时会快速生成好默认的 package.json 安装依赖 在新建的项目下用 npm 安装依…

深入理解动态代理

为什么需要动态代理 对于代码的增强逻辑我们是清楚具体实现的,一种方式是增强逻辑作为委托类,被其他业务类调用, 这样会有很多重复代码,而且,当需要根据动态参数来决定增强逻辑时,重复代码会更多,逻辑会更不清晰 二,也是动态代理产生的原始需求,解决类爆照问题, 所以…

Cherry Studio之DeepSeek联网/本地,建属于自己的AI助理!

上一篇文章&#xff0c;讲了DeepSeek-R1部署到本地的方法。这一篇文章&#xff0c;我们让DeepSeek再一次升级&#xff0c;通过图形化界面来交互&#xff0c;从而变成我们的AI助理&#xff0c;让DeepSeek R1发挥最大实力&#xff01; 首选需要借助硅基流动的API接口&#xff0c…

IGBT的两级关断

IGBT&#xff08;绝缘栅双极型晶体管&#xff09;的两级关断&#xff08;Two-stage turn-off&#xff09;是一种优化关断过程的方法&#xff0c;主要用于减少关断时的电压过冲和dv/dt&#xff08;电压变化率&#xff09;过高的问题&#xff0c;特别是在大功率应用中&#xff08…

【STM32】ADC

本次实现的是ADC实现数字信号与模拟信号的转化&#xff0c;数字信号时不连续的&#xff0c;模拟信号是连续的。 1.ADC转化的原理 模拟-数字转换技术使用的是逐次逼近法&#xff0c;使用二分比较的方法来确定电压值 当单片机对应的参考电压为3.3v时&#xff0c;0~ 3.3v(模拟信号…

0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeek R1模型

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 0基础…

Chapter3:结构化程序设计

参考书籍&#xff1a;《C#边做边学》&#xff1b; 3.结构化程序设计 3.1 结构化程序设计的3种基本结构 顺序结构&#xff1a;先执行 A {\rm A} A语句&#xff0c;再执行 B {\rm B} B语句&#xff0c;两者是顺序执行的关系&#xff1b; 选择结构&#xff1a;根据所定选择条件为…

白话文实战Nacos(保姆级教程)

前言 上一篇博客 我们创建好了微服务项目,本篇博客来体验一下Nacos作为注册中心和配置中心的功能。 注册中心 如果我们启动了一个Nacos注册中心,那么微服务比如订单服务,启动后就可以连上注册中心把自己注册上去,这过程就是服务注册。每个微服务,比如商品服务都应该注册…

智能理解 PPT 内容,快速生成讲解视频

当我们想根据一版 PPT 制作出相对应的解锁视频时&#xff0c;从撰写解锁词&#xff0c;录制音频到剪辑视频&#xff0c;每一个环节都需要投入大量的时间和精力&#xff0c;本方案将依托于阿里云函数计算 FC 和百炼模型服务&#xff0c;实现从 PPT 到视频的全自动转换&#xff0…

IEC61850标准下的数据和数据模型服务的详细介绍

目录 一、摘要 二、概述 三、详细介绍 1、读服务器目录(GetServerDirectory) 2、读逻辑设备目录(GetLogicalDeviceDirectory) 3、读逻辑节点目录(GetLogicalNodeDirectory) 4、读全部数据值(GetAllDataValues) 5、读数据值(GetDataValues) 6、设置数据值(SetDataValues…

R语言LCMM多维度潜在类别模型流行病学研究:LCA、MM方法分析纵向数据

全文代码数据&#xff1a;https://tecdat.cn/?p39710 在数据分析领域&#xff0c;当我们面对一组数据时&#xff0c;通常会有已知的分组情况&#xff0c;比如不同的治疗组、性别组或种族组等&#xff08;点击文末“阅读原文”获取完整代码数据&#xff09;。 然而&#xff0c;…

5. 【.NET 8 实战--孢子记账--从单体到微服务--转向微服务】--微服务基础工具与技术--Nacos

一、什么是Nacos Nacos 是阿里巴巴开源的一款云原生应用基础设施&#xff0c;它旨在简化微服务架构中服务治理和配置管理的复杂性。通过 Nacos&#xff0c;服务在启动时可以自动注册&#xff0c;而其他服务则可以通过名称来查找并访问这些注册好的实例。同时&#xff0c;Nacos…

VUE项目中实现权限控制,菜单权限,按钮权限,接口权限,路由权限,操作权限,数据权限实现

VUE项目中实现权限控制&#xff0c;菜单权限&#xff0c;按钮权限&#xff0c;接口权限&#xff0c;路由权限&#xff0c;操作权限&#xff0c;数据权限实现 权限系统分类&#xff08;RBAC&#xff09;引言菜单权限按钮权限接口权限路由权限 菜单权限方案方案一&#xff1a;菜单…

【网络安全】服务器安装Docker及拉取镜像教程

文章目录 1. 安装 Docker2. 拉取镜像3. 运行 Ubuntu 容器4. 执行相关操作5. 退出并停止容器1. 安装 Docker # 更新软件包索引 sudo apt update# 安装必要的依赖 sudo apt install -y ca-certificates curl gnupg

elementplus 使用日期时间选择器,设置可选范围为前后大于2年且只能选择历史时间不能大于当前时间点

需求&#xff1a;时间选择器可选的时间范围进行限制&#xff0c;-2年<a<2年且a<new Date().getTime()核心&#xff1a;这里需要注意plus版没有picker-options换成disabled-date属性了&#xff0c;使用了visible-change和calendar-change属性逻辑&#xff1a;另设一个参…

将 AMD Zynq™ RFSoC 扩展到毫米波领域

目录 将 AMD Zynq™ RFSoC 扩展到毫米波领域Avnet XRF RFSoC 系统级模块适用于 MATLAB 的 Avnet RFSoC Explorer 工具箱5G mmWave PAAM 开发平台突破性的宽带毫米波波束成形特征&#xff1a;OTBF103 Mathworks Simulink 模型优化毫米波应用中的射频信号路径 用于宽带毫米波上/下…