谈谈UVM中的Factory机制

为了遵循验证计划完成不同的验证任务,用户可能需要扩展原始的通用验证环境。验证过程是动态的,可重用验证环境的开发人员无法预见未来每一个corner case验证的项目需求。 

UVM factory是经典软件开发中工厂设计模式(factory design pattern)的实现,该模式用于创建通用代码,从而在运行时(run-time)确定对象的确切子类型。对于以下可重用的类定义:

//UVM Non-Factory Allocation

 class driver extends uvm_component
 `uvm_component_utils(driver)
 function new(string name, uvm_component parent);
 super.new(name,parent);
 endfunction
 virtual task drive_transfer();
 ...
 endtask
 endclass:driver
 class agent extends uvm_component; // bad example that uses new()
 `uvm_component_utils(agent)
 driver my_driver;
 function new(string name, uvm_component parent);
 super.new(name,parent);
 // create the driver
 my_driver= new ("my_driver", this) ; // using new()
 endfunction
 endclass:agent

这个示例直接使用new()创建对象。假设用户希望将agent集成到验证平台中并希望使用drive_transfer()任务打印信息,我们需要实现新的driver组件:

class my_project_driver extends driver;
 `uvm_component_utils(my_project_driver)
 virtual task drive_transfer();
 super.drive_transfer();
 `uvm_info("MYIHF01","Finisheddriving transfer", UVM_LOW)
 endtask
 function new(string name, uvm_component parent);
 . . .
 endfunction
 endclass:my_project_driver

agent会实例化先前定义的driver而不是扩展的my_project_driver,验证平台集成人员需要修改agent类等所有直接或者间接实例化driver的类定义,这会造成代码修改的连锁反应。

UVM factory引入了一种优雅的解决方案(elegant solution),允许对当前的类进行覆盖。UVM factory不是使用new()而是使用create()方法进行对象创建:

//Using the UVM Factor 

 class agent extends uvm_component;
 `uvm_component_utils(agent)
 driver my_driver;
 function new(string name, uvm_component parent);
 super.new(name,parent);
 // create the driver
 my_driver= driver::type_id::create("my_driver",this);
 endfunction
 endclass:agent

创建此代码后,用户可以使用以下方法覆盖所有driver:

set_type_override_by_type(driver::get_type(),my_project_driver::get_type());

或者用户可以使用以下方法替换driver的特定实例:

set_inst_override_by_type("env0.agent0.driver",driver::get_type(),
my_project driver::get_type();

要使用UVM factory,应遵循以下步骤:

 

1.在factory内注册所有类。

通过使用宏`uvm_object_utils`uvm_component_utils自动实现objects和components的注册。

 

2.使用API创建objects和components。

my_driver = driver :: type_id :: create(“ my_driver”,this);

3.在创建(create)对象之前,使用类型(type)和实例(instance)替换当前类。

 class state extends uvm_component;
 `uvm_component_utils(state)
 function new(string name, uvm_componentparent);
 super.new(name, parent);
 endfunction : new
 function void end_of_elaboration();
 this.print();
 endfunction : end_of_elaboration
 endclass : state

 class florida extends state;
 `uvm_component_utils(florida)
 function new(string name, uvm_componentparent);
 super.new(name, parent);
 endfunction : new
 endclass : florida

 class new_york extends state;
 `uvm_component_utils(new_york)
 function new(string name, uvm_componentparent);
 super.new(name, parent);
 endfunction : new
 endclass : new_york

 state my_state1, my_state2;
 // Start UVM Phases
 initial begin
 my_state1 =state::type_id::create("my_state1", null);
 `uvm_info("INF01",{“my_state1.type=",my_state1.get_type_name()},UVM_LOW)
 // set factory to allocate new_yorkstate whenever a state is created
 factory.set_type_override_by_type(state::get_type(),new_york::get_type());
 my_state2 =state::type_id::create("my_state2", null);
 `uvm_info("INF02",{"my_state2.type=",my_state2.get_type_name()},UVM_LOW)
 #100 $finish;
 end

Line1:定义state基类

Lines10-21: 从基类派生florida和new_york类
Line 22: 声明两个state句柄state1和state2.
Lines 25-26: 使用factory API state::type_id::create(...)创建state对象

Line28: 使用factory 机制替换当前基类

Line29:创建新对象

最终打印结果是:

UVM_INFO ./test.sv(51)@0: reporter [INFO1] my_state1.type=state
UVM_INFO ./test.sv(54)@0: reporter [INFO2]my_state2.type=new_york

往期精彩

谈谈UVM中事务级建模(TLM)的Port和Export

谈谈UVM中事务级建模(TLM)的uvm_tlm_fifo

谈谈UVM中事务级建模(TLM)的Analysis Ports 和Exports

  • 5
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值