UVM:factory 机制(1)

前言

如果我们用Systemverilog构建验证平台,构建好了之后,想改变平台中的某个组件,例如将driver改成driver_new,我们需要重新定义一下driver_new,当然也可以直接从driver继承。但是我们还需要在driver对象例化的地方将driver drv;改成driver_new drv;,如果需要多个组件的更新、以及多次的平台复用,那代码量巨大,而且每次改变都要深入平台内部,非常繁琐。

基于上述问题,UVM提出了factory机制,译作工厂机制,来源于设计模式中的工厂机制。

factoy机制意思是:通过将拓展类在工厂注册,可实现环境内部组件的创建与对象的重载

factory机制主要针对构成验证环境层次的uvm_component及其子类,以及构成环境配置属性和数据传输的uvm_object及其子类

`

一、注册

使用factory机制的第一步就是将类注册到工厂。这个factory是整个全局仿真中存在且唯一的“机构”,所有被注册的类才能使用factory机制。

使用宏进行注册

`uvm_component_utils(my_agent)					//component注册macro
`uvm_component_utils_begin(my_agent)			//注册factory的同时,可注册field automation
//...
`uvm_component_utils_end

`uvm_component_param_utils(my_driver)			//参数化的component注册,例class my_driver #(int width = 32) extends uvm_driver;
`uvm_component_utils_param_begin(my_driver)			//注册factory的同时,可注册field automation
//...
`uvm_component_utils_param_end

`uvm_object_utils(my_transaction)				//object注册macro
`uvm_object_utils_begin(my_transaction)				//注册factory的同时,可注册field automation
//...
`uvm_object_utils_end

`uvm_object_param_utils(my_sequence)			//参数化的object注册,例class my_sequence #(int width = 32) extends uvm_sequence;
`uvm_object_utils_param_begin(my_sequence)			//注册factory的同时,可注册field automation
//...
`uvm_object_utils_param_end

UVM-1.2中,这个所谓的全局唯一factory其实存在于uvm_coreservice_t类中,该类包含了UVM核心组件和方法。该类不是uvm_component和uvm_object型的,而是独立于UVM的。

二、创建

创建就是实例化对象,所有注册到factory的类均可通过factory独特的方式实例化对象。

但factory的独特方式,实际上也是调用了new函数,也是先创建句柄再赋予对象。
代码如下(示例):

class my_agent extends uvm_agent;
	`uvm_component_utils(my_agent)						//注册
	function new(string name, uvm_component parent);
		super.new(name,parent);
	endfunction
	//...
endclass
my_agent agt;											//创建my_agent句柄
agt = my_agent::type_id::create("agt", env);			//factory独特且最常用的例化方式,创建了my_agent实例并返回句柄,本质还是调用的my_agent::new(name,parent);

class my_sequence extends uvm_sequence;
	`uvm_object_utils(my_sequence)						//注册
	function new(string name);							//object不属于uvm层次结构,不需要parent
		super.new(name);
	endfunction
	//...
endclass
my_sequence seq;									//创建my_sequence句柄
seq = my_sequence::type_id::create("seq");			//factory独特且最常用的例化方式,创建了name为"seq"的my_sequence实例,并返回句柄

2.1. 建议使用 drv = my_driver::type_id::create(“drv”,agt); 创建

简单好用,当然也有其他方法,不过可能涉及到$cast或是引入factory

2.2. 使用factory创建

提供了原型

  //...\questasim64_2020.1\verilog_src\uvm-1.2\src\base\uvm_factory.svh
  pure virtual function
      uvm_object    create_object_by_type    (uvm_object_wrapper requested_type,  
                                              string parent_inst_path="",
                                              string name=""); 
  pure virtual function
      uvm_component create_component_by_type (uvm_object_wrapper requested_type,  
                                              string parent_inst_path="",
                                              string name, 
                                              uvm_component parent);
  pure virtual function
      uvm_object    create_object_by_name    (string requested_type_name,  
                                              string parent_inst_path="",
                                              string name=""); 

● uvm_object_wrapper requested_type:用于表示对象类型
函数原型为

 //...\questasim64_2020.1\verilog_src\uvm-1.2\src\base\uvm_object.svh
virtual class uvm_object extends uvm_void; 
	extern static function uvm_object_wrapper get_type ();
	extern virtual function uvm_object_wrapper get_object_type ();
	...
endclass

其他形参,string parent_inst_path、string name和uvm_component parent依次表示父节点路径(object不需要)、对象name、父节点句柄

直接使用factory方法创建,注意要用全局唯一uvm_factory类对象factory调用上述方法,并且上述方法返回类型不是uvm_object就是uvm_component,所以要用$cast作类型转换。

例子如下

class my_test extends uvm_test;
	`uvm_component_utils(my_test);
	my_transaction t;
	...
	function void build_phase(uvm_phase phase);
		super.build_phase(phase);
		void'($cast(t,factory.create_object_by_type(my_transaction::get_type(),,"t")));			//注意使用void'()令返回为空
		...
	endfunction
endclass

2.3. 使用uvm_component方法创建

一般是在component内创建其他component或object,所以uvm_component类也提供了创建的方法

 //...\questasim64_2020.1\verilog_src\uvm-1.2\src\base\uvm_component.svh
  extern function uvm_component create_component (string requested_type_name, 
                                                  string name);
  extern function uvm_object create_object (string requested_type_name,
                                            string name="");

也要注意使用$cast做类型转换
————————————————
版权声明:本文为CSDN博主「Starry丶」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Starry__/article/details/122930959

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值