UVM与工厂模式和策略模式

Strategy & Factory Pattern

背景

问题

方案 - 朴素

//pseudocode, create and run case
task create_and_run_test()
	if(uvm_test_name=="test_case_1") begin
		u_test_case_1 = new();
		u_test_case_1.run_test_case_1();
	end
	else if(uvm_test_name=="test_case_2") begin
		u_test_case_2 = new();
		u_test_case_2.run_test_case_2();
	end
	else if(uvm_test_name=="test_case_3") begin
		u_test_case_3 = new();
		u_test_case_3.run_test_case_3();
	end
	else if(uvm_test_name=="test_case_4") begin
		u_test_case_4 = new();
		u_test_case_4.run_test_case_4();
	end
	… 
endtask

缺点:
增加/删除/修改用例,都要修改上述代码。假如有5万条用例,上述代码量就需要十几万,维护成本太大。
思考:can we do better?
If/else if/else知道的太多。
各个分支都是用例创建和用例运行,能不能归一化处理?

方案 - 策略&工厂模式

抽象
归一化:
1 定义uvm_test基类,所有的用例都是继承自uvm_test的子类
2 基类uvm_component中定义了归一化的接口build_phase()/demo_phase()…

image.png

image.png

//pseudocode 
task create_and_run_test()
	uvm_component uvm_test_top;
	uvm_test_top = factory.create(test_name); //pseudocode, need $cast
	foreach demo_phase in phase_collection:
		foreach demo_component in uvm_test_top:
			demo_component.demo_phase()  //invoke phase process of component
endtask 

说明
1 工厂根据用例名创建对应的用例对象;
2 用统一的接口uvm_test_top: uvm_component(基类)指向工厂生产的用例对象(子类)

class factory
	function uvm_component create(string test_name)
		if(test_name =="test_case_1")
			return new test_case_1;
		else if(test_name =="test_case_2")
			return new test_case_2;
		else if(test_name =="test_case_3")
			return new test_case_3;
		… … 
	endfunction
endclass

优点
工厂对外提供了统一的接口create来创建对象,保证用户仅用一行代码完成对象创建。
问题:
工厂内部每个test_case_x的创建依然存在分支,增加/删除/修改用例都要牵扯到工厂的修改
思考
如何干掉工厂内部的分支?

class factory; 
	function uvm_component create(string name);
		test_case_x_type = test_case_type_dict[test_name];
		test_case_x_object = create object using test_case_x_type;
		return test_case_x_object;
	endfunction
endclass 

image.png

假设
存在一个字典test_case_type_dict[string],将所有的用例的class类型-用例名存储到一个字典中,构造用例时,通过用例名选出类型,然后用类型创建对象。
问题
语言不支持用一个字典容器存储class类型。
思考
如何给用例名和用例类型之间建立映射?

为每个class类型(test_case_x:type)套上唯一的轻量级wrapper object() (test_case_x_wrapper),
然后将wrapper object 存入字典中。

思考
字典无法存储类型,但可以存储对象,因此为每个类型(test_case_x:type)套上一个轻量级对象(test_case_x_wrapper),然后将对象放入字典中m_type_names[string]。
image.png

image.png

step0: 为每个用例类创建唯一的wrapper object(注册),并将用例名<->wrapper对象注册到关联数组m_type_names[string]中。
step1: 根据test_name从m_type_names[string]中选出test_case_x_wrapper
step2: 使用test_case_x_wrapper中的test_case_x类型构造test_case_x的object

image.png

image.png

function void uvm_factory::register(uvm_object_wrapper obj)
  m_type_names[obj.get_type_name()] = obj;
  m_types[obj] = 1;
endfunction

总结

Strategy pattern
模式说明:
指对象有某个行为,但是在不同的场景中,该行为有不同的实现算法
定义了一族算法(业务规则);
封装了每个算法;
这族的算法可互换代替(interchangeable)。
UVM应用:
UVM Testcase
UVM sequence
UVM Driver ?

Factory pattern
模式说明:
工厂通常是一个用来创建其他对象的对象。工厂是构造方法的抽象,用来实现不同的分配方案。
应用场景:
创建对象需要大量重复的代码。可以把这些代码写在工厂基类中。
创建对象需要访问某些信息,而这些信息不应该包含在复合类中。
UVM应用:
uvm_factory
run_test()

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值