【验证技能树】UVM 源码解读08 — Factory 机制真的有必要吗?—— 一个被误解的依赖反转设计
聚焦 RISC-V / CPU / SoC 验证实践。所有结论,默认都——得验。
在很多工程实践中,Factory 经常被贴上这样的标签:“复杂、啰嗦、没必要,用 new 不香吗?”
但如果你真的去读 UVM 源码,会发现:Factory 解决的根本不是“怎么 new 对象”,而是“谁依赖谁”。
这篇文章,我们从源码和设计动机出发,重新理解 Factory 的存在意义。
一、一个非常真实的工程疑问
你可能也有过这样的想法:
-
• component 都是我写的 -
• testbench 架构也很稳定 -
• override 用得很少 -
• 大多数时候 new()就能解决
那问题来了:
UVM 为什么要为“new 一个对象”,引入一整套 Factory 机制?
答案是:
Factory 从来不是为“简单项目”准备的。
二、先说结论(非常重要)
Factory 的本质不是“对象创建工具”,而是 UVM 在验证框架层面实现的“依赖反转(IoC)”。
理解这一点,Factory 才会突然变得合理。
三、如果没有 Factory,会发生什么?
我们先假设一个没有 Factory 的世界。
1️⃣ 直接 new 的后果
driver = new("driver", this);
这行代码意味着什么?
这个 component,已经“硬编码依赖”了具体实现类。
后果是:
-
• driver 类型一旦写死 -
• 所有替换都要改源码 -
• test 无法注入不同实现 -
• reuse 边界非常脆弱
2️⃣ 工程规模一大,问题立刻显现
在 SoC 级项目中,你一定会遇到:
-
• 同一个 agent,不同 project 不同 driver -
• 同一个 monitor,功能验证 / 性能验证不同实现 -
• 同一个 env,不同 test 需要不同行为
如果靠 new:
-
• 修改点极多 -
• 风险极大 -
• 验证环境不可控
四、UVM Factory 的真正目标
UVM Factory 要解决的不是“怎么 new”,而是:
让“高层结构”不依赖“底层实现”。
这正是依赖反转原则(Dependency Inversion Principle):
-
• 高层模块不依赖低层模块 -
• 二者都依赖抽象
在 UVM 里:
-
• 抽象 = base class -
• 绑定关系 = Factory
五、从源码看:Factory 在哪里“插了一刀”?
UVM Factory 的关键切入点只有一个:
对象创建的那一刻
你不再写:
driver = new(...);
而是:
driver = my_driver::type_id::create("driver", this);
这行代码的真实含义是:
“我声明我要一个 my_driver 接口级别的对象,至于具体给我什么,由 Factory 决定。”
六、Override:不是“替换类”,而是“注入依赖”
这是 Factory 最容易被误解的地方。
1️⃣ 常见误解
override = 把 A 换成 B
这是表象。
2️⃣ 真正的语义
factory.set_type_override( base_driver::get_type(), perf_driver::get_type());
真正发生的是:
在不修改任何 env / agent 代码的前提下,改变系统的“依赖绑定关系”。
这在软件工程里,叫:
-
• Dependency Injection -
• Late Binding -
• Runtime Polymorphism
七、为什么 Factory 是“全局的”?
这是很多人吐槽的点。
“为什么 Factory 是 singleton?看起来很丑。”
但从设计角度看,这是刻意的。
原因只有一个:
依赖关系,必须在“系统级”统一管理。
如果每个 component 有自己的 Factory:
-
• override 规则会冲突 -
• 行为不可预测 -
• 验证环境失去一致性
UVM 选择的是:
-
• 一个全局 Factory -
• 明确、可追溯的 override 顺序
八、为什么工程中 Factory 经常“用得很少”?
这是一个非常现实的问题。
1️⃣ 很多项目,依赖关系很稳定
-
• agent / driver 不常变 -
• reuse 范围有限 -
• 项目周期短
👉 Factory 的收益不明显。
2️⃣ Factory 的价值是“未来收益”
Factory 的成本是“现在付”,收益是“将来用”。
而很多项目:
-
• 活不到那个阶段 -
• 或者没机会演进
3️⃣ 但这不代表 Factory 没价值
而是说明:
Factory 解决的是“架构级问题”,不是“写代码快不快”的问题。
九、一个非常重要的工程建议
不要为了用 Factory 而用 Factory
正确策略是:
-
• base class 用 Factory -
• 可变点用 Factory -
• 稳定点直接 new
UVM 本身也不是“全 Factory 派”。
当你觉得 Factory 多余时,说明你当前项目的复杂度,还没逼你用它。
但当你开始频繁 copy env、改 driver、分叉平台时,Factory 会突然变成“救命设计”。
十、总结
UVM Factory 的核心价值,不在“创建对象”,而在“切断依赖”。
它让验证环境从“写死结构”,变成“可配置系统”。
这也是为什么 Factory 在小项目里显得多余,在大系统中却不可或缺。
夜雨聆风
