UVM与模板模式

模板模式

关键字

泛型参数化类模板类

问题

class proc_1;
	string data;
	static int counter;
endclass
class proc_2;
	int data;
	static int counter;
endclass
proc_1 u_proc_1 = new();
proc_2 u_proc_2 = new();

上述proc_1与proc_2类的代码基本一致,唯一的差异就在data的类型,proc_1的data类型是string,proc_2的data类型是int。
问题
仅仅为了data的类型编写了两个类,这两个类又高度相似,如果data的类型更多,如何处理?比如新增real, shortreal, bit, logic时,又需要增加编写对应的class?
思考
如何简化上述代码?如何能将变化的和不变的区分开来?

措施

参数化类(泛型类):

class proc #(type T=int);
	T data;
	static int counter;
endclass

typedef proc#(string) proc_1;
typedef proc#(int) proc_2;

proc_1 u_proc_1 = new();
proc_2 u_proc_2 = new();

说明
class proc #(type T=int)中井号(#)来定义泛型类。在引用泛型类时(proc#(string) proc_1),还可以使用井号来提供参数赋值或覆盖的列表。

注意

在class proc中,
proc#(string) ::counter与proc#(int)::counter是两个完全独立的计数器。

静态类属性将在时间0之前分配和初始化。
但是,一旦声明带有参数的泛型类,静态类属性就不再成立。
泛型类在specialization时才会分配和初始化静态属性,每个specialization都有一个唯一的实例及其静态属性的初始化。

应用场景

不同的类型,相同的操作

uvm工厂模式

类注册时为每个类套一个独一无二的wrapper,但个体类千差万别,利用泛型类屏蔽差异性。

image.png

UVM TLM

virtual class uvm_port_base #(type IF=uvm_void) extends IF;
  typedef uvm_port_base #(IF) this_type;
  ... 
endclass

说明: 在编写类时,若遇到在不同情况下,继承不同基类的的场景,可参考上述UVM源码的编码,将基类参数化(IF),能大幅度减少编码,提高复用性。

class uvm_blocking_put_imp #(type T=int, typeIMP=int) extends uvm_port_base #(uvm_tlm_if_base #(T,T));
  `UVM_IMP_COMMON(`UVM_TLM_BLOCKING_PUT_MASK,"uvm_blocking_put_imp",IMP)
  `UVM_BLOCKING_PUT_IMP (m_imp, T, t)
endclass

说明:这是一个继承自己模板类的模板类

限制

function int func_1(int data);
   return data
endfunction

function string func_2(string data);
   return data
endfunction

systemVerilog无法解决上述的问题,不过可以通过泛型类包起来,或者宏等方式解决重用问题。

参考

https://zhuanlan.zhihu.com/p/369969387

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值