UVM 工厂机制深入
更新时间:2026-10-01。已有 工厂 override,本文把工厂的匹配规则、覆盖优先级和“为什么我 override 不生效”讲透。
本文要回答的问题
- 类型覆盖和实例覆盖谁优先,路径怎么写?
- 为什么有时明明 override 了,跑的还是原类?
- 怎样用工厂最省事地派生一整套环境?
一、create 才能被覆盖
工厂只对经 type_name::type_id::create("name", parent) 创建的对象生效。若代码里直接 new(),该对象不进工厂表,任何 override 对它都不起作用——这是 override 失效最常见原因。
二、两种覆盖
systemverilog
// 类型覆盖:所有该类型都替换
orig_seq::type_id::set_type_override(bad_seq::get_type());
// 实例覆盖:只替换某条层次路径的对象
drv_t::type_id::set_inst_override(my_drv::get_type(),
"env.agt.driver", this);- set_type_override:全局替换该类型(受注册关系约束)。
- set_inst_override:按“完整实例路径”精确替换,优先级高于类型覆盖。
- 匹配时工厂沿注册类型和实例路径查表,实例覆盖先于类型覆盖命中。
三、派生环境的工作流

基线环境稳定后,新场景只需在 build 阶段做几处工厂覆盖(换序列注入错误、换 driver 变体)和配置调整,其余组件完全复用。
四、常见坑
- 目标对象用
new()创建,绕过工厂。 - override 的类没注册工厂(缺
uvm_*_utils)或类型不兼容。 - 在对象创建之后才 override,为时已晚(应在 build 阶段、create 之前)。
- 实例路径写错,覆盖没命中却以为生效。
- 多层覆盖冲突,没用
print_override()检查实际结果。
小结
工厂以 create 为前提,实例覆盖优先于类型覆盖,且必须在 build/create 前设置;它让“少量替换派生整套环境”成为现实。下一篇 低功耗验证端到端。
总结
UVM 工厂让你用“最小差异”派生整套环境:它只对经 type_id::create() 创建的对象生效,直接 new() 会绕过工厂——这是 override 失效的最常见原因;覆盖分两种,set_type_override 全局替换某类型,set_inst_override 按完整实例路径精确替换且优先级高于类型覆盖,二者都必须在 build 阶段、对象 create 之前设置。基线 env/test 稳定后,新场景只需做几处工厂覆盖(换 sequence 注入错误、换 driver/agent 变体)加配置调整、其余组件全部复用。排查“override 不生效”时看四类原因:目标用了 new、覆盖类没注册工厂/类型不兼容、设置晚于创建、实例路径写错,用 print_override() 核对实际结果。