注册表类编写

编写代理类;

  代理基类必须包含用于创建对象的纯虚方法和用于返回类名的方法;

  拓展的代理类需要实现参数化传递希望创建对象的类型和类名;

  代理类的调用伴随着factory的调用;

  当仿真时间为0时,编译器会发现代理类的me尚未被初始化,进而创建工厂对象,并返回工厂类的句柄;

  然后代理类创建代理对象,调用工厂类的注册函数完成对对象句柄的注册;

  与静态注册表不同,动态注册表一开始只注册了工厂类和需要调用的代理类,没有对需要创建的对象进行创建;

  因此,工厂类中注册表关联数组存储的是代理类的句柄而不是组件类或测试类的句柄;

  运行过程中,工程量通过读取命令行找到需要创建的对象,再从关联数组中索引指定的代理类,调用该代理类进行对象创建,再将句柄返还。

virtual class svm_object_wrapper;
    pure virtual function string get_type_name();
    pure virtual function svm_object create_object(string name);
endclass
class svm_component_registry #(type T=svm_component, string Tname="<unknown>") extends svm_object_wrapper;
    typedef svm_component_registry #(T,Tname) this_type;
    virtual function string get_type_name();
        return Tname;
    endfunction
    local static this_type me = get();
    static function this_type get();
        if (me == null) begin
            svm_factory f = svm_factory::get();
            me = new();
            f.register(me);
        end
        return me;
    endfunction
    virtual function svm_object create_object(string name="");
        T obj;
        obj = new(name);
        return obj;
    endfunction
    static function T create(string name);
        create = new(name);
    endfunction
endclass
class svm_factory;
    static svm_object_wrapper m_type_names[string];
    static svm_factory m_inst;
    static function svm_factory get();
        if (m_inst == null) m_inst = new();
        return m_inst;
    endfunction
    static function void register(svm_object_wrapper c);
        m_type_names[c.get_type_name()] = c;
    endfunction
    static function svm_component get_test();
        string name;
        svm_object_wrapper test_wrapper;
        svm_component test_comp;
        if (!$value$plusargs("SVM_TESTNAME=%s", name)) begin
            $display("FATAL +SVM_TESTNAME not found");
            $finish;
        end
        $display("%m found +SVM_TESTNAME=%s", name);
        test_wrapper = svm_factory::m_type_names[name];
        $cast(test_comp, test_wrapper.create_object(name));
        return test_comp;
    endfunction
endclass
`define svm_component_utils(T) \
    typedef svm_component_registry #(T,`"T`") type_id; \
    virtual function string get_type_name(); \
        return `"T`"; \
    endfunction
class TestBase extends svm_component;
    Environment env;
    `svm_component_utils(TestBase)
    function new(string name);
        super.new(name);
        $display("%m");
        env = new();
    endfunction
    virtual task run_test();
    endtask
endclass
program automatic test;
    initial begin
        svm_component test_obj;
        test_obj = svm_factory::get_test();
        test_obj.run_test();
    end
endprogram

  

posted @ 2025-07-22 09:54  NoNounknow  阅读(10)  评论(0)    收藏  举报