SystemVerilog UVM create_object_by_name 详解

SystemVerilog UVM create_object_by_name 详解(含代码示例)

create_object_by_nameUVM factory(工厂)机制uvm_factory 类的核心成员方法:

1. 用于通过字符串形式的类型名,在仿真运行时动态创建 UVM 对象(uvm_object/uvm_component 派生类实例)

2. 是 UVM 实现类型覆盖、平台解耦、高可复用性的核心能力之一。

先举例详细说明:

import uvm_pkg::*;
`include "uvm_macros.svh"

// 基础sequence类
class base_seq extends uvm_sequence #(uvm_sequence_item);
    `uvm_object_utils(base_seq) // 注册到factory,映射类名字符串"base_seq"
    
    function new(string name = "base_seq");
        super.new(name);
    endfunction

    virtual task body();
        `uvm_info("BASE_SEQ", "This is base sequence body!", UVM_LOW)
    endtask
endclass

// 扩展sequence类,用于演示类型覆盖
class extend_seq extends base_seq;
    `uvm_object_utils(extend_seq) // 注册到factory,映射类名字符串"extend_seq"
    
    function new(string name = "extend_seq");
        super.new(name);
    endfunction

    virtual task body();
        `uvm_info("EXTEND_SEQ", "This is extend sequence body! Override success!", UVM_LOW)
    endtask
endclass

// 测试用例顶层
class base_test extends uvm_test;
    `uvm_component_utils(base_test)
    uvm_sequencer #(uvm_sequence_item) sqr; // 定义sequencer

    function new(string name = "base_test", uvm_component parent = null);
        super.new(name, parent);
    endfunction

    virtual function void build_phase(uvm_phase phase);
        super.build_phase(phase);
        sqr = uvm_sequencer#(uvm_sequence_item)::type_id::create("sqr", this);
        
        // 【可选】类型覆盖:全局把base_seq替换为extend_seq
        // 打开这行注释,factory会自动创建extend_seq实例,无需修改create逻辑
        // factory.set_type_override_by_name("base_seq", "extend_seq");
    endfunction

    virtual task run_phase(uvm_phase phase);
        uvm_sequence seq;
        uvm_object seq_obj;
        
        phase.raise_objection(this);
        
        // 核心:通过类名字符串创建base_seq实例
        `uvm_info("TEST", "Create sequence by name", UVM_LOW)
        seq_obj = uvm_factory::get().create_object_by_name(
            "base_seq",       // 类名字符串,可以直接写死,即直接写成"extend_seq",即直接指定创建 extend_seq 类的实例(想运行哪一个sequence,就可以把其名字放在这里)
            sqr.get_full_name(), // 父sequencer的完整路径
            "test_seq"        // 实例名称:可以随意给,它只是一个 “实例名称”,不影响功能
        );

        // 容错与类型转换
        if(seq_obj == null) begin
            `uvm_fatal("TEST", "Create sequence failed!")
        end
        if(!$cast(seq, seq_obj)) begin
            `uvm_fatal("TEST", "Cast sequence failed!")
        end

        // 启动sequence
        seq.start(sqr);
        
        phase.drop_objection(this);
    endtask
endclass

// 仿真入口
module top;
    initial begin
        run_test("base_test");
    end
endmodule

UVM 源码中该方法的完整原型如下:

extern virtual function uvm_object create_object_by_name (
    string requested_type_name,
    string parent_inst_path = "",
    string name = "",
    uvm_component parent = null
);
参数名核心作用关键注意事项
requested_type_name【必填】要创建的对象的类名字符串必须与uvm_*_utils宏注册的类名完全一致(区分大小写),类必须完成 UVM factory 注册,否则创建失败返回 null
parent_inst_path【可选】对象所属父实例的 UVM 完整层级路径,用于 ** 实例级覆盖(instance override)** 规则匹配通常用父组件的get_full_name()获取,如你代码中的sqr[ddrsys_id].get_full_name()
name【可选】创建出的实例的名称,对应类new(name)函数的入参用于 UVM 打印、路径索引,无特殊需求可与类名保持一致
parent【可选】父组件句柄,仅用于uvm_component派生类的创建uvm_sequence/item等纯 object 类型无需传递,保持默认 null 即可

注意:

返回uvm_object类型的基类句柄,指向新创建的对象实例:

  • 若类型名未注册、factory 匹配失败,返回null
  • 必须通过$cast转换为目标派生类句柄,才能访问派生类的自定义成员 / 方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值