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

factory机制

factory机制

本质

  • factory机制是UVM框架中的一个重要组件,用于创建和管理组件实例
  • 它通过注册组件类型根据类型创建实例,实现了组件的动态创建管理
  • factory机制的核心是uvm_factory类,它负责注册组件类型创建组件实例管理组件实例

目的:

  • 实现组件的动态创建管理
  • 确保组件在树形结构中的正确位置和命名

1. 核心逻辑

  • factory机制的核心是uvm_factory类,它负责注册组件类型创建组件实例管理组件实例
  • uvm_factory类包含以下主要方法:
    1. register:用于注册组件类型,将组件类添加到m_type_map关联数组中
    2. create_component_by_type:根据组件类型创建组件实例,根据类型从m_type_map中获取组件类型字符串,然后调用组件类的create方法创建实例
class uvm_factory;// 注册组件类型function void register(uvm_component_type type);// 检查类型是否已注册if (m_type_map.exists(type)) begin// 处理类型已注册错误end// 将类型添加到映射中m_type_map[type] = type.get_type_name();endfunction// 根据类型创建组件实例function uvm_component create_component_by_type(uvm_component_type type, string name, uvm_component parent);// 检查类型是否已注册if (!m_type_map.exists(type)) begin// 处理类型未注册错误end// 创建组件实例uvm_component comp = type.create(name, parent);// 设置组件的父组件comp.set_parent(parent);// 返回创建的组件实例return comp;endfunction
endclass

2. 注册组件类型

  • 组件类型注册是指将组件类注册到uvm_factory中,以便后续根据类型创建组件实例
  • 注册过程包括将组件类添加到m_type_map关联数组中,键为组件类型,值为组件类型的字符串表示

3. 根据类型创建组件实例

  • 根据类型创建组件实例是指根据组件类型从uvm_factory中获取组件类型字符串,然后调用组件类的create方法创建组件实例
  • 创建过程包括检查类型是否已注册、调用组件类的create方法创建实例、设置组件的父组件和返回实例

4. 宏注册

  • 宏注册是指使用UVM提供的工具宏,将组件类或对象类注册到uvm_factory
  • 对于组件类,使用uvm_component_utils(T)宏;对于对象类,使用uvm_object_utils(T)
  • 宏注册过程包括在类定义中添加宏调用,将类名作为参数传递给宏
  • 宏调用会自动生成必要的代码,包括类型注册、创建方法和类型名称声明等,最终将类型注册到uvm_factory

宏注册的实现代码逻辑

uvm_component_utils(T)宏为例,其内部实现逻辑如下:

// uvm_component_utils宏的实现
`define uvm_component_utils(T) \`m_uvm_component_registry_internal(T,T) \`uvm_type_name_decl(`"T") \// 其中m_uvm_component_registry_internal宏展开为:
`define m_uvm_component_registry_internal(T,S) \typedef uvm_component_registry#(T,`"S") type_id; \static function type_id get_type(); \return type_id::get(); \endfunction \virtual function uvm_object_wrapper get_object_type(); \return type_id::get(); \endfunction \function uvm_component create_component(string name, uvm_component parent); \uvm_component tmp; \tmp = type_id::create(name, parent); \return tmp; \endfunction// uvm_type_name_decl宏展开为:
`define uvm_type_name_decl(N) \const static string type_name = N; \virtual function string get_type_name(); \return type_name; \endfunction

当我们在组件类中使用uvm_component_utils(my_component)时,宏会展开为:

class my_component extends uvm_component;// 宏展开后的代码typedef uvm_component_registry#(my_component, "my_component") type_id;static function type_id get_type();return type_id::get();endfunctionvirtual function uvm_object_wrapper get_object_type();return type_id::get();endfunctionfunction uvm_component create_component(string name, uvm_component parent);uvm_component tmp;tmp = type_id::create(name, parent);return tmp;endfunctionconst static string type_name = "my_component";virtual function string get_type_name();return type_name;endfunctionfunction new(string name, uvm_component parent);super.new(name, parent);endfunction
endclass

宏注册的核心是通过uvm_component_registry类将组件类型注册到uvm_factory中。当调用type_id::get()时,会创建并返回一个唯一的registry实例,同时将该类型注册到factory中。

5. 利用factory的重载的特点与方法

  • factory机制支持组件和对象类型的重载,允许在运行时替换默认类型为其他类型,实现灵活的测试配置

  • 重载分为两种类型:

    • 类型重载:对所有该类型的实例进行替换
    • 实例重载:仅对特定路径的实例进行替换
  • 重载过程是在创建实例之前通过factory的方法设置,当调用create方法时,factory会根据重载规则创建相应的类型实例

  • 内置重载方法:

    • 类型重载方法:
      • set_type_override_by_type(original_type, override_type, replace)
      • set_type_override_by_name(original_type_name, override_type_name, replace)
    • 实例重载方法:
      • set_inst_override_by_type(relative_inst_path, original_type, override_type)
      • set_inst_override_by_name(relative_inst_path, original_type_name, override_type_name)
  • 命令行重载:

    • 可以在命令行中使用-uvm_set_type_override-uvm_set_inst_override选项来设置类型和实例重载
  • 覆盖优先级

    • 类型重载:根据注册顺序,后注册的类型会覆盖先注册的类型
    • 实例重载:根据路径顺序,后设置的实例重载会覆盖先设置的实例重载
    • 命令行重载:在命令行中使用-uvm_set_type_override-uvm_set_inst_override选项来设置类型和实例重载,命令行设置的重载会覆盖程序中设置的重载
  • override机制必须满足的三个条件:

    • 原始类(被覆盖的类)和覆盖类(新的派生类)都必须使用uvm_component_utils或uvm_object_utils宏在工厂中注册
    • 原始类必须通过工厂的type_id::create()方法创建
    • 覆盖操作(调用set_type_override或set_inst_override)必须在目标对象被创建之前进行

UVM的树形结构实现

UVM的树形结构本质是通过uvm_component构造函数实现的,具体机制如下:

uvm_component具有如下变量和方法:

  • 变量

    1. m_parent:指向父组件的指针
    2. m_children:关联数组,存储子组件的指针
    3. m_children_by_handle:关联数组,根据组件句柄存储子组件的指针
  • 方法

    1. new:构造函数,用于创建组件实例
    2. m_add_child:将子组件添加到当前组件的子组件列表中

1. 构造函数的核心逻辑

uvm_component的构造函数是树形结构形成的关键,其核心代码如下:

function uvm_component::new (string name, uvm_component parent);uvm_root top;uvm_coreservice_t cs;super.new(name);// 获取核心服务和根节点cs = uvm_coreservice_t::get();top = cs.get_root();  // 获取uvm_root实例// 当parent为null时,自动设置为uvm_rootif (parent == null) beginparent = top;end// 检查子组件名称唯一性if (parent.has_child(name) && this != parent.get_child(name)) begin// 处理名称冲突错误end// 设置父组件并添加到父组件的子列表中m_parent = parent;set_name(name);if (!m_parent.m_add_child(this)) beginm_parent = null;end// 继承父组件的域m_domain = parent.m_domain;// 其他初始化...
endfunction

2. 树形结构的形成过程

  1. 根节点初始化

    • uvm_root是一个特殊的uvm_component,作为整个组件树的根节点

    • 通过uvm_coreservice_t::get().get_root()获取唯一的根节点实例

    • 核心代码:

       static local uvm_root m_inst;  // 静态局部变量,存储**单例实例**function uvm_root uvm_root::new();super.new("**top**", null);// 防止创建多个根实例if (m_inst != null) begin`uvm_fatal_context("UVM/ROOT/MULTI","Attempting to construct multiple roots",m_inst)return;endm_inst = this;  // 将当前实例赋值给静态变量// 其他初始化...endfunction
      
  2. 父组件设置

    • 当创建组件时不指定父组件(设为null),系统会自动将其父组件设置为uvm_root
    • 这样确保了所有组件最终都归属于同一个根节点下
    • 通常,uvm_test的parent是null,其他组件的parent都是uvm_test
  3. 子组件添加

    • 通过m_parent.m_add_child(this)当前组件添加到父组件的子组件列表

3. 树形结构的特点

  • 唯一性:每个组件在其父组件下都有唯一的名称
  • 层次化:通过点号分隔的层次化名称表示组件在树中的位置
  • 完整性:所有组件都属于同一个组件树,根节点是uvm_root
  • 可遍历性:通过get_first_childget_next_child等方法可以遍历组件树
http://www.jsqmd.com/news/433049/

相关文章:

  • 计算机图形学几何工具算法详解pdf下载
  • Andrew Stankevich Contest 42 (ASC 42) 总结
  • Python的函数
  • jQuery CSS 类
  • JavaScript let 和 const:深入理解与最佳实践
  • Android12 Rk3588 系统APK签名文件使用方法
  • 文章索引
  • RAG——为什么说RAG是AI 2.0时代的“杀手级”应用
  • skills 核心原理
  • 题解:P14121 [SCCPC 2021] Dont Really Like How The Story Ends
  • 广州商业街区美陈氛围升级设计公司怎么选?避坑攻略+靠谱名单
  • 二.uboot叙述
  • 题解:P5870 [SEERC 2018] Modern Djinn
  • 宠物健康有保障:2026上海服务出色的宠物医生盘点,腹腔镜绝育/猫咪乳糜胸手术/猫咪绝育/宠物医院,宠物专家口碑推荐 - 品牌推荐师
  • 代码复查方法:问题发现系统
  • Go 性能优化技巧
  • 金融行业大数据实践:数据目录在风控中的应用
  • 吃透 Nginx 核心知识点:从静态部署到反向代理与负载均衡
  • 【精准医学与基因组学:技术实现】第一章:基因组数据处理工程 pipeline 1.3 Snakemake实战:基于Python的规则定义、DAG执行图优化、HPC集群与云环境部署
  • AutoCAD 硬件加速无法开启(仅显示虚拟设备 gdi17.hdi)的解决方法
  • AI原生应用:人机协作的未来已来,你准备好了吗?
  • 11.数据类型拓展
  • 题解:P14556 [ROI 2013 Day2] 星际航程
  • 题解:UVA11350 Stern-Brocot Tree
  • 数字孪生架构设计及系统开发难点有哪些?
  • ansible常见的模块
  • java学习笔记1.16
  • VBA 64位API声明语句第018讲
  • Lotus扩散模型深度估计精研
  • Mask2Former实例分割实战:Swin大模型解析[特殊字符]