我是靠谱客的博主 自然超短裙,最近开发中收集的这篇文章主要介绍UVM——工厂机制,覆盖方法,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

工厂的意义:为了更方便的替换验证环境中的实例或已注册的类型,使注册机制更加灵活。

UVM验证环境的两大类:uvm_component,uvm_object。                                                   

从关系上来看,uvm_component 继承于 uvm_report_objec t继承于 uvm_object。uvm_component实现了验证环境的层次化,uvm_object实现了环境的配置和数据的传输。

uvm_component是静态的组件类,对应sv中的generator,stimulator,monitor,agent,checker,refmod,env,test等

uvm_object是动态的验证场景,对应sv中的transaction,从generator流向stimulator的数据包。

---------------------------------------------------------------------------------------------------------------------------------

工厂类的三个步骤:定义、注册、创建

class comp1 extends uvm_component;         //定义comp类
    'uvm_component_utils(comp1)            //注册
    function new(string name = "comp1", uvm_component parent = null);       //创建
        super.new(name, parent);
        $display($sformatf("%s is creates", name));
    endfunction: new
endclass

component类中的new函数中的参数(name,parent)不可进行更改,其中parent是例化该实例(comp1)的对象

class obj1 extends uvm_object;         //定义comp类
    'uvm_object_utils(obj1)            //注册
    function new(string name = "obj1");       //创建
        super.new(name);
        $display($sformatf("%s is creates", name));
    endfunction: new
endclass

 object类相较于component类,new函数中只有一个参数(name)

---------------------------------------------------------------------------------------------------------------------------------

 如果需要创建component或object对象,可采用下列方式:

//创建uvm_component对象
comp_type::type_id::create(string name, uvm_component parent);

//创建uvm_object对象
object_type::type_id::create(string name);

可以简单的理解为工人(comp_type)从工厂里找到模具(type_id),并放到机器上进行加工(create) 。create会在后台调用new函数进行创建。

---------------------------------------------------------------------------------------------------------------------------------

 uvm_coreservice_t类包括:

  • uvm_factory:注册,覆盖,例化
  • report_server:全局,消息统筹,报告
  • tr_database:全局,记录transaction
  • get_root():返回当前UVM环境的结构顶层对象

需要注意, uvm_coreservice_t不是uvm_component或uvm_object类型,并且它所包含的类都是唯一的。

---------------------------------------------------------------------------------------------------------------------------------

对象创建方法

  1. type_id
    c2 = comp1::type_id::create("c2", null);
    c2 = obj1::type_id::create("o2");
  2. creat
  3. 通过coreservice句柄拿到factory句柄里的方法进行创建:
    create_component_by_name(),
    create_component_by_type()
    create_object_by_name()
    create_object_by_type()

 component中name和parent的作用:uvm_component::new(name, parent)保留这两个参数,可以将结构一层一层的连接起来,如同“钩子”勾住上层结构。而object中没有parent参数,所以不会显示在UVM层次中。

---------------------------------------------------------------------------------------------------------------------------------

覆盖 override

在SV中,如果需要修改别人的driver,就会对源代码进行改动,导致:1.影响他人使用;2.遇到无法修改的ip。因此UVM提供覆盖方法,将原来的类型替换成另一个类型,在覆盖之后,原来用于创建原属类型的请求,将由工厂创建新的替换类型,但是新的类型一定要继承于原有类型,且原有类型和新类型都需要注册

使用覆盖的优点:

  1. 无需修改原始代码,保证源代码的封装性,也确保句柄不会失效
  2. 使顶层修改更加方便,可使用子类覆盖父类,也可使用不同的对象修改代码行为

 覆盖方法:

  1.  类型替换set_type_override(),UVM层次结构下所有的原有类型都被覆盖类型所替换。
  2.  实例替换set_inst_override(),在某些位置中的原有类型会被覆盖类型所替代。

 

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

	class comp1 extends uvm_component;
		`uvm_component_utils(comp1)
		
		function new(string name="comp1", uvm_component parent=null);
			super.new(name, parent);
			$display($sformatf("comp1::%s is created", name));
		endfunction

		virtual function void hello(string name);
			$display($sformatf("comp1::%s said hello!", name));
		endfunction
	endclass

	class comp2 extends comp1;
		`uvm_component_utils(comp2)
	
		function new(string name="comp2", uvm_component parent=null);
			super.new(name, parent);
			$display($sformatf("comp2::%s is created", name));
		endfunction

		function void hello(string name);
			$display($sformatf("comp2::%s said hello!", name));
		endfunction
	endclass

	comp1 c1, c2;
	initial begin
		comp1::type_id::set_type_override(comp2::get_type());    //用comp2覆盖comp1
		c1 = new("c1");        //因为使用new创建而非工厂创建,所以结果为comp1::c1 is created
		c2 = comp1::type_id::create("c2", null);//首先调用comp1的new()打印comp1::c2 is 
                                                //created,然后调用comp2的new()函数打印
                                                //comp2::c2 is created此处就是用new创
                                                //建和工厂创建的区别
		c1.hello("c1");
		c2.hello("c2");     //先调用comp1类型,那么会查看comp1::hello(),又由于该方法在定义时
                            //被指定为虚函数,这就通过了多态性的方法调用,转而调用了
                            //comp2::hello()函数
	end
endmodule

 输出结果

 

--------------------------------------------------------------------------------------------------------------------------------

最后是factory的三个核心要素:注册、创建、覆盖

  • 'uvm_{component,object}_utils
  • uvm_{component,object}::type_id::create()
  • set_{type,inst}_override{,_by_type}() 

最后

以上就是自然超短裙为你收集整理的UVM——工厂机制,覆盖方法的全部内容,希望文章能够帮你解决UVM——工厂机制,覆盖方法所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(43)

评论列表共有 0 条评论

立即
投稿
返回
顶部