如何通过UVM工厂覆盖使child_class继承ext_class的约束?
问题描述
现有三个UVM类定义如下:
基类base_class:
class base_class extends uvm_object; ... ... rand int a; constraint a_c {a inside {[0:100]};} endclass
扩展类ext_class(继承自base_class,重载约束a_c):
class ext_class extends base_class; constraint a_c {a inside {[100:150]};} endclass
子类child_class(直接继承自base_class,无额外约束):
class child_class extends base_class; endclass
需求:通过UVM工厂将base_class替换为ext_class,同时让child_class也能获得ext_class中定义的约束a_c。
解决方案
要实现需求,核心是让child_class的实例继承ext_class的约束,以下是两种可行方案:
方案一:修改child_class继承关系(结合工厂替换)
- 调整
child_class的父类为ext_class,使其自动继承目标约束:
class child_class extends ext_class; endclass
- 在UVM环境的
build_phase中注册工厂替换规则,让所有base_class实例被替换为ext_class:
// 方式一:直接调用工厂API uvm_factory::get().set_type_override_by_type(base_class::get_type(), ext_class::get_type()); // 方式二:使用UVM宏简化 set_type_override(base_class::get_type(), ext_class::get_type());
原理:
- 修改继承关系后,
child_class直接继承ext_class的重载约束; - 工厂替换规则确保所有原本创建
base_class实例的地方,实际生成ext_class对象,同时child_class作为ext_class子类,自然拥有目标约束。
方案二:不修改child_class,通过工厂替换为自定义扩展类
如果无法修改child_class源代码,可创建继承ext_class的新类,再通过工厂替换child_class:
- 定义继承
ext_class的新类,保留原child_class特性:
class ext_child_class extends ext_class; // 复制原child_class的所有成员与逻辑 endclass
- 在
build_phase中注册双重替换规则:
// 替换base_class为ext_class set_type_override(base_class::get_type(), ext_class::get_type()); // 替换child_class为ext_child_class set_type_override(child_class::get_type(), ext_child_class::get_type());
原理:
- 原
child_class默认继承base_class的约束,通过工厂替换为ext_child_class(继承ext_class),创建child_class实例时实际生成的是ext_child_class对象,从而获得目标约束; - 同时替换
base_class为ext_class,确保其他直接使用base_class的场景也能生效。
关键注意点
- UVM工厂的类型替换仅对通过工厂创建的对象生效,直接用
new()实例化的对象不受影响; - SystemVerilog中,子类同名约束会覆盖父类的对应约束,因此
ext_class的a_c会完全替代base_class的原约束,无需额外关闭父类约束。
内容的提问来源于stack exchange,提问作者user1978273
相关产品推荐
相关产品推荐

