UVM源码--uvm_component 浅析(一)

news/2024/12/22 23:59:34/

目录

1. uvm_object

2. uvm_component

3. 为什么在uvm_component 例化是需要指定一个parent?

4.uvm_component 的树形结构是如何组织起来的?

5. 静态函数与非静态函数的区别:

 6. uvm_root 的单实例实现思路:

7. run_test 的背后

1. uvm_object

uvm_object是一个相对简单的类,它提供了一些基本的接口,如用于 field_automation 机制的 printcopypack 等,一些鉴别身份的,如 get_nameget_type_nameget_full_name 等。

2. uvm_component

对于 uvm_component 来说,有两大特点,一是它是一种树形组织结构中的一个结点,在其 new 的时候都要指定一个 parent,二是它有 phase 的概念。

3. 为什么在uvm_component 例化时需要指定一个parent?

假如不指定parent,compoent A 中有一个成员变量component B,在B例化的时候使用B=new(“B”),不添加parent,这样会导致在整体的环境框架中A 不知道B是他的孩子,因为没有指定,如果有些用户需要遍历整个UVM 树,那他是找不到的。所以我们一般会规范的加上parent,一旦加上parent,在A的m_children 数组中,会出现B 的指针。只有这样才能让 A 知道 B 是自己的孩子,同时也才能让B知道 A 是自己的父母。

4.uvm_component 的树形结构是如何组织起来的?

实现这样的功能当然离不开三个重要的变量他们分别是:

  1. m_parent, component类型,用于表示父类节点,在new 函数的源码里边有 m_parent= parent ; 主要目的是实现树形结构的父类定位,这样在子类进行例化的时候就能顺其自然的找到自己的父类;
  2. m_children, string类型关联数组,实际上在m_parent= parent后,会调用m_parent的m_add_child函数,将自己的孩子加入到自己的函数中,其中在m_add_child函数中就有这么一条语句m_children[child.get_name()] = child; 这里的child 就是变量实例化的时候赋值的string, 父类会将其加入到关联数组中。也就有了一个叫B的孩子;
  3. m_child_by_handle,component 类型的关联数组,在m_children[child.get_name()] = child后,会紧跟这这样一条命令m_children_by_handle[child] = child;表示其索引和内容都是child的指针。
5. 静态函数与非静态函数的区别:
  1. 静态函数必须要先例化,才可以调用其内部的方法,而非静态函数则不需要;
  2. 静态函数的调用使用点.进行,而非静态函数使用双冒号::
 6. uvm_root 的单实例实现思路:

我们知道uvm_root 作为uvm环境的根,具有唯一性,另外,uvm_root 作为一个根,它是开始,在new的时候,第一个new的调用也是我们在代码实现的过程中必须要考虑的问题,因为一般而言,只要先实例化才可以使用其内部的函数,就比如new().所以当前两个问题需要解决:

先解决第一个,如何在不实例化的前提下,调用其内部的new()函数,使用静态函数可以做到,这也是上边介绍静态函数和非静态函数的初衷,在uvm_component.new()中,对uvm_top::get()的调用目的就在于此,get()的内部会继续调用uvm_root.new(),因为root 在调用new()之前没有实例化,所以uvm_root 的方法必须声明为static,其类型的变量也一样;

第二个问题,uvm_root的唯一性如何实现,其实很简单,在调用函数是首先判断uvm_root 指针是否为null,如果不为null,就说明已经有一个root了.如果没有root,就应该对他调用new函数。当然uvm_root 的对象也应该是static类型,不然调用会出错哦。

在源码中,将这种执行方式封装到get函数里边,get是静态函数,所以在uvm_component.new函数的源码里边会看到uvm_root  top;  top = uvm_root::get();

在271行,提到了uvm_root::new(),其实在uvm_root::new()中不需要任何参数,它调用 super.new,传入的 name 参数为__top__, 而 parent 参数为 null

又回到uvm_component.new(),看一下下边关于uvm_root相关的代码:

在uvm_component 中,判断parent=null && name == __top__的时候,就知道这是uvm的根,直接返回。

但是,如果在分支的实例化中,将uvm_component 传入null有会发生什么?

在new函数中还有这样的一条判断:

如果传入的parent == null,默认该节点就是top。

7. run_test 的背后

我们知道在验证环境搭建好后,启动仿真的方式有两种:一种是直接使用run_test(“ ”), 直接将case名称写进去;另一种方法是在运行的时候输入控制命令+UVM_TESTNAME=“ ”;

这是我们能看到的,也是我们经常用到的,实际上背后是这样的:

在调用tun_test函数后,run_test 会调用 uvm_root 的 run_test,uvm_root::run_test的主要代码如下:

329行调用了uvm_cmdline_processsor的get_arg_values函数,对UVM_TESTNAME后边的字符进行统计,返回值是统计的个数,具体的字符是被放在test_names的队列中。下边有两个判断,第一个判断如果返回的test_name_count>0, 说明有传case名称进来,直接默认就为一个,拿队列index=0 的值(此处不是get,值还在),第二个判断如果发现test_name_count > 1,会报出warning,并打印。

拿到case名称之后,会进行创建实例,uvm_root会首先判断该实例是否已经被创建,如下363行,如果创建说明有问题。一般不会创建。

整个 run_test 关键的部分在于 368 和 369 行的 cast 函数中调用factory. create_ component_ by_name,这个函数将会根据输入的 case 的名字来创建这个 case 的一个实例。371 行用于判断实例创建是否成功,如果没有成功,说明这个 case 根本没有在 factory 中注册过,会给出出错提示。一般的,当我们在指定 case 的时候如果输错了名字就会给出这个错误提示。


http://www.ppmy.cn/news/1201392.html

相关文章

antv/x6 自定义html节点并且支持动态更新节点内容

antv/x6 自定义html节点 效果图定义一个连接桩公共方法注册图形节点创建html节点动态更新节点内容 效果图 定义一个连接桩公共方法 const ports {groups: {top: {position: top,attrs: {circle: {r: 4,magnet: true,stroke: #cf1322,strokeWidth: 1,fill: #fff,style: {visib…

Unity之NetCode多人网络游戏联机对战教程(6)--NetworkTransform组件

文章目录 前言NetworkTransform是什么玩家移动脚本NetworkTransform字段讲解Synchronizing ("Syncing")ThresholdsLocal spaceInterpolationSlerp PositionUse Quaternion SynchronizationUse Quaternion CompressionUse Half Float PrecisionAuthority modesServer …

Hive从入门到大牛【Hive 学习笔记】

文章目录 什么是HiveHive的数据存储Hive的系统架构MetastoreHive VS Mysql数据库 VS 数据仓库 Hive安装部署Hive的使用方式命令行方式JDBC方式 Set命令的使用Hive的日志配置Hive中数据库的操作Hive中表的操作 Hive中的数据类型基本数据类型复合数据类型ArrayMapStructStruct和M…

Pytorch 里面torch.no_grad 和model.eval(), model.train() 的作用

torch.no_grad: 影响模型的自微分器,使得其停止工作;这样的话,数据计算的数据就会变快,内存占用也会变小,因为没有了反向梯度计算,当然,我哦们也无法做反向传播。 model.eval() 和model.train()…

JAVA前端开发介绍

以一个网站为例包括网站设计、前端开发、程序开发等。网站设计就是网站的外观,平面的东西。程序开发也好理解就是功能实现。而前端开发,简单来说,就是把平面效果图转换成网页,把静态转换成动态。它的工作包括了:切图、写样式、做鼠…

Flink(一)【WordCount 快速入门】

前言 学完了 Hadoop、Spark,本想着先把 Kafka、Flume 这些工具先学完的,但想了想还是把核心的技术先学完最后再去把那些工具学学。 最近心有点累哈哈哈,偷偷立个 flag,反正也没人看,明年的今天来这里还愿哈&#xff0c…

【网络】五中IO模型介绍 + 多路转接中select和poll服务器的简单编写

高级IO 前言正式开始前面的IO函数简单过一遍什么叫做低效的IO钓鱼的例子同步IO和异步IO五种IO模型阻塞IO非阻塞IO信号驱动多路转接异步IO 小结 代码演示非阻塞IO多路转接select介绍简易select服务器timeout 为 nullptrtimeout 为 {0, 0}timeout 为 {5, 0}调用accept select编写…

Unreal PythonScriptPlugin

Unreal PythonScriptPlugin 文章目录 Unreal PythonScriptPluginPython vs UnLua官方文档PyStubDoString 示例代码,引擎里有很多插件已经用 py 写编辑器脚本了 unreal.get_editor_subsystem(unreal.LevelEditorSubsystem).load_level("/Game/maps/UVlayoutTes…