UVM 工厂机制 完整可编译运行 Demo

整套结构:transaction → base_driver → ext_driver → agent → env → base_test + 3个测试用例实现:不覆盖、类型全局覆盖、实例精准覆盖 三种场景,一键跑通看工厂效果。

1. 事务类 my_transaction.sv

复制代码
class my_transaction extends uvm_sequence_item;
  `uvm_object_utils(my_transaction)

  rand bit [31:0] data;

  function new(string name="my_transaction");
    super.new(name);
  endfunction

  virtual function void do_print(uvm_printer printer);
    super.do_print(printer);
    printer.print_field("data", data, 32);
  endfunction
endclass

2. 基础驱动 base_driver.sv(被替换基类)

复制代码
class base_driver extends uvm_driver#(my_transaction);
  `uvm_component_utils(base_driver)

  function new(string name="base_driver", uvm_component parent=null);
    super.new(name, parent);
  endfunction

  virtual task run_phase(uvm_phase phase);
    super.run_phase(phase);
    `uvm_info("BASE_DRV", "我是原始 base_driver 正常工作", UVM_MEDIUM)
  endtask
endclass

3. 扩展驱动 ext_driver.sv(工厂替换子类)

必须继承基类 + 同样注册宏

复制代码
class ext_driver extends base_driver;
  `uvm_component_utils(ext_driver)

  function new(string name="ext_driver", uvm_component parent=null);
    super.new(name, parent);
  endfunction

  virtual task run_phase(uvm_phase phase);
    super.run_phase(phase);
    `uvm_info("EXT_DRV", "我是被工厂覆盖进来的 ext_driver", UVM_MEDIUM)
  endtask
endclass

4. Agent 封装 agent.sv

复制代码
class my_agent extends uvm_agent;
  `uvm_component_utils(my_agent)

  base_driver drv;  // 句柄声明基类,工厂动态实例化

  function new(string name="my_agent", uvm_component parent=null);
    super.new(name, parent);
  endfunction

  virtual function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    // 工厂创建,不写死 new
    drv = base_driver::type_id::create("drv", this);
  endfunction
endclass

5. 顶层环境 env.sv

复制代码
class my_env extends uvm_env;
  `uvm_component_utils(my_env)

  my_agent agt;

  function new(string name="my_env", uvm_component parent=null);
    super.new(name, parent);
  endfunction

  virtual function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    agt = my_agent::type_id::create("agt", this);
  endfunction
endclass

6. 基础测试用例 base_test.sv

复制代码
class base_test extends uvm_test;
  `uvm_component_utils(base_test)

  my_env env;

  function new(string name="base_test", uvm_component parent=null);
    super.new(name, parent);
  endfunction

  virtual function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    env = my_env::type_id::create("env", this);
  endfunction

  virtual function void end_of_elaboration_phase(uvm_phase phase);
    // 打印拓扑,查看实例完整路径
    uvm_root::get().print_topology();
    // 打印工厂注册&覆盖信息
    uvm_factory::get().print();
  endfunction
endclass

7. 三个实战测试用例(核心工厂用法)

用例 1:test_no_override ------ 不做任何覆盖,用原生 base_driver

复制代码
class test_no_override extends base_test;
  `uvm_component_utils(test_no_override)

  function new(string name="test_no_override", uvm_component parent=null);
    super.new(name, parent);
  endfunction
endclass

用例 2:test_type_override ------ 全局类型覆盖

所有 base_driver 全部替换为 ext_driver

复制代码
class test_type_override extends base_test;
  `uvm_component_utils(test_type_override)

  function new(string name="test_type_override", uvm_component parent=null);
    super.new(name, parent);
  endfunction

  virtual function void build_phase(uvm_phase phase);
    // 必须先super,再设覆盖,再创建
    super.build_phase(phase);

    // 类型覆盖:全局替换
    base_driver::type_id::set_type_override(ext_driver::get_type());
  endfunction
endclass

用例 3:test_inst_override ------ 实例路径精准覆盖

只替换 uvm_test_top.env.agt.drv 这一个实例

复制代码
class test_inst_override extends base_test;
  `uvm_component_utils(test_inst_override)

  function new(string name="test_inst_override", uvm_component parent=null);
    super.new(name, parent);
  endfunction

  virtual function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    uvm_factory fac = uvm_factory::get();

    // 实例覆盖:指定完整路径
    fac.set_inst_override_by_type(
      base_driver::get_type(),
      ext_driver::get_type(),
      "uvm_test_top.env.agt.drv"
    );
  endfunction
endclass

8. 仿真启动文件 tb.sv

复制代码
module tb;
  initial begin
    run_test();
    // 分别跑:
    // run_test("test_no_override");
    // run_test("test_type_override");
    // run_test("test_inst_override");
  end
endmodule

仿真现象说明

  1. test_no_override 打印:我是原始 base_driver 正常工作

  2. test_type_override 同样的 base_driver::type_id::create,实际生成 ext_driver,打印扩展驱动信息

  3. test_inst_override只匹配指定路径实例被替换,其他同类型组件不受影响


关键考点再总结(必背)

  1. 工厂三步骤:宏注册 → build 阶段设覆盖 → type_id::create 创建
  2. 禁止直接 new(),否则绕开工厂,覆盖无效
  3. 覆盖优先级:实例覆盖 > 类型覆盖
  4. 覆盖必须写在 build_phase,创建前设置才生效
  5. 基类、派生类都必须注册宏,否则覆盖失败
相关推荐
liuluyang5304 小时前
UVM工厂机制
uvm·工厂机制
liuluyang5305 小时前
UVM工厂机制(二)
uvm·工厂机制
liuluyang5306 天前
SystemVerilog常用关键词与函数
uvm·systermverilog
liuluyang5306 天前
SV主要关键词详解
fpga开发·uvm·sv
liuluyang53021 天前
clk_mux_seq sv改进
fpga开发·uvm
谷公子的藏经阁1 个月前
DVCon 2025 论文精华导读及下载链接
ai·论文·systemverilog·uvm·dvcon
蓝天下的守望者3 个月前
SystemVerilog中 `timescale的使用问题
systemverilog·uvm·vcs
蓝天下的守望者4 个月前
uvm_field_automation机制学习
uvm
Piri_LogicBldr4 个月前
【验证技能树】UVM 源码解读11 -- TLM2 —— Blocking vs Non-blocking 背后的建模取舍
uvm·芯片验证·验证技能