2. 覆盖默认组件类型
任务目标
在UVM验证环境中,默认情况下uvm_component工厂根据类型名创建基类对象。本案例通过set_type_override_by_type将基类driver替换为派生类driver,并验证工厂实际创建的是派生类对象。
实现方案
定义基类base_driver和派生类ext_driver,在测试类中注册override,通过create方法创建组件并检查其类型。核心验证逻辑:使用UVM内置的get_type_name()和$cast确认对象类型。
关键完整代码
```systemverilog
// 文件: factory_override_test.sv
`include "uvm_macros.svh"
import uvm_pkg::*;
// 基类driver
class base_driver extends uvm_component;
`uvm_component_utils(base_driver)
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
virtual task run_phase(uvm_phase phase);
`uvm_info("BASE", "base_driver run_phase", UVM_LOW)
endtask
endclass
// 派生类driver
class ext_driver extends base_driver;
`uvm_component_utils(ext_driver)
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
virtual task run_phase(uvm_phase phase);
`uvm_info("EXT", "ext_driver run_phase", UVM_LOW)
endtask
endclass
// 测试类:注册override并验证
class factory_override_test extends uvm_test;
`uvm_component_utils(factory_override_test)
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
// 注册override:将base_driver替换为ext_driver
set_type_override_by_type(base_driver::get_type(),
ext_driver::get_type());
// 通过工厂创建组件(应返回ext_driver实例)
base_driver drv;
drv = base_driver::type_id::create("drv", this);
// 验证1:类型名检查
if (drv.get_type_name() == "ext_driver")
`uvm_info("PASS", "类型名验证通过: ext_driver", UVM_LOW)
else
`uvm_error("FAIL", $sformatf("类型名错误: %s", drv.get_type_name()))
// 验证2:$cast检查(动态类型是否为ext_driver)
ext_driver ext_drv;
if ($cast(ext_drv, drv))
`uvm_info("PASS", "$cast验证通过: 对象是ext_driver类型", UVM_LOW)
else
`uvm_error("FAIL", "$cast失败: 对象不是ext_driver类型")
endfunction
virtual function void end_of_elaboration_phase(uvm_phase phase);
super.end_of_elaboration_phase(phase);
// 打印工厂注册信息(可选调试)
uvm_factory::get().print();
endfunction
endclass
// 顶层模块
module top;
initial begin
run_test("factory_override_test");
end
endmodule
```
运行方式
```bash
# 使用任意支持UVM-1.2或IEEE 1800.2的仿真器
# VCS示例:
vcs -sverilog +incdir+$UVM_HOME/src $UVM_HOME/src/uvm.sv \
factory_override_test.sv -R -l run.log
# Questa/ModelSim示例:
vlog -sv +incdir+$UVM_HOME/src $UVM_HOME/src/uvm.sv factory_override_test.sv
vsim -c -do "run -all; quit" work.top
```
验证方法与判定标准
- 通过条件:仿真日志中出现两条
PASS信息,且无FAIL或UVM_ERROR。 - 预期输出(由代码逻辑唯一确定):
UVM_INFO @ 0: ... [PASS] 类型名验证通过: ext_driver
UVM_INFO @ 0: ... [PASS] $cast验证通过: 对象是ext_driver类型
- 附加观察:
run_phase中打印的EXT信息(而非BASE)进一步确认执行的是派生类方法。
关键点说明
set_type_override_by_type必须在create之前调用,本案例在build_phase中完成。- 两个类都必须注册到工厂(
`uvm_component_utils),否则override不生效。 - 验证使用两种互补方式:
get_type_name()检查静态注册名,$cast检查实际动态类型。