3. UVM组件家族:核心构件与事务级建模

UVM组件家族是搭建验证环境的基础骨架。每个组件在事务级建模(TLM)中承担特定职责,并通过标准化的接口进行通信。本章将系统梳理 uvm_component、uvm_object、uvm_agent、uvm_driver、uvm_monitor、uvm_sequencer 和 uvm_scoreboard 的核心特性、继承关系与典型用法。

3.1 两大基类:uvm_object 与 uvm_component

UVM中所有数据对象和组件都派生自两个核心基类:uvm_object 和 uvm_component。理解它们的区别是掌握UVM组件层次结构的第一步。

特性 uvm_object uvm_component
层次结构 无层次,独立对象 有层次,属于组件树
生命周期 通过 new() 创建,手动管理 通过 create() 创建,由phase自动管理
phase机制 不支持 支持完整的phase执行
典型用途 事务、配置、序列项 driver、monitor、agent、env
构建方式 new("name") new("name", parent)
实践要点: 所有需要参与phase自动调度、拥有父组件或子组件的类,必须从 uvm_component 派生。纯数据对象(如事务描述)则从 uvm_object 派生,以获得工厂注册、复制、比较等内置功能。

3.2 核心驱动组件:uvm_driver 与 uvm_sequencer

uvm_driver 和 uvm_sequencer 是验证环境中激励生成与发送的核心搭档。它们通过TLM端口实现事务级通信。

  • uvm_sequencer:负责管理序列(sequence)的执行顺序,向driver发送事务请求。
  • uvm_driver:从sequencer获取事务,并将其转换为接口上的信号级时序。

典型连接方式如下:

class my_driver extends uvm_driver #(my_transaction);
  `uvm_component_utils(my_driver)

  function new(string name, uvm_component parent);
    super.new(name, parent);
  endfunction

  virtual task run_phase(uvm_phase phase);
    forever begin
      seq_item_port.get_next_item(req);
      // 将事务驱动到接口
      drive_transaction(req);
      seq_item_port.item_done();
    end
  endtask
endclass
关键接口: seq_item_port 是driver内建的TLM端口,用于从sequencer拉取事务。务必在每次驱动完成后调用 item_done(),以通知sequencer释放该事务。

3.3 监测与检查组件:uvm_monitor 与 uvm_scoreboard

uvm_monitor 负责被动监测DUT接口,收集事务级数据;uvm_scoreboard 负责比对预期结果与实际行为,完成验证的最终检查。

组件 职责 TLM端口方向
uvm_monitor 监测接口信号,打包成事务对象 输出(analysis_port)
uvm_scoreboard 接收事务,执行比对或检查 输入(analysis_export)

monitor通过 analysis_port 将采集到的事务广播给所有订阅者(如scoreboard)。scoreboard通过 analysis_export 接收事务,并在内部维护参考模型或比对队列。

3.4 容器组件:uvm_agent

uvm_agent 是一个容器组件,用于封装特定协议接口所需的driver、monitor和sequencer。它提供两种工作模式:

  • 主动模式(is_active = UVM_ACTIVE):包含driver、monitor和sequencer,可主动驱动激励。
  • 被动模式(is_active = UVM_PASSIVE):仅包含monitor,只监测不驱动。

agent的典型结构如下:

class my_agent extends uvm_agent;
  `uvm_component_utils(my_agent)

  my_driver    driver;
  my_sequencer sequencer;
  my_monitor   monitor;

  function new(string name, uvm_component parent);
    super.new(name, parent);
  endfunction

  virtual function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    monitor = my_monitor::type_id::create("monitor", this);
    if (get_is_active() == UVM_ACTIVE) begin
      driver    = my_driver::type_id::create("driver", this);
      sequencer = my_sequencer::type_id::create("sequencer", this);
    end
  endfunction

  virtual function void connect_phase(uvm_phase phase);
    if (get_is_active() == UVM_ACTIVE) begin
      driver.seq_item_port.connect(sequencer.seq_item_export);
    end
  endfunction
endclass

3.5 组件家族关系总览

下图展示了UVM组件家族的核心成员及其在验证环境中的层次关系:

UVM组件家族核心关系图 uvm_object uvm_component uvm_driver uvm_monitor uvm_sequencer uvm_scoreboard uvm_agent(容器组件) 说明: • uvm_object 是所有数据对象的基类,无层次结构,不参与phase。 • uvm_component 是所有硬件组件的基类,有层次结构,参与phase自动调度。 • uvm_agent 可配置为主动模式(含driver+sequencer+monitor)或被动模式(仅monitor)。 • driver与sequencer通过TLM端口连接,monitor通过analysis_port向scoreboard发送事务。

3.6 组件间TLM通信路径

下图展示了验证环境中各组件之间的事务级通信路径:

组件间TLM通信路径 uvm_sequencer uvm_driver DUT uvm_monitor uvm_scoreboard seq_item_port 信号级驱动 信号监测 analysis_port TLM通信要点: • sequencer与driver之间通过TLM阻塞传输端口(seq_item_port)通信。 • monitor通过analysis_port广播事务,scoreboard通过analysis_export订阅接收。

3.7 组件选择速查表

在实际搭建验证环境时,可根据以下速查表快速确定每个组件的使用场景:

组件 基类 是否参与phase 典型数量 主要TLM端口
uvm_driver uvm_component 是 每个接口1个 seq_item_port(输入)
uvm_monitor uvm_component 是 每个接口1个 analysis_port(输出)
uvm_sequencer uvm_component 是 每个接口1个 seq_item_export(输出)
uvm_scoreboard uvm_component 是 通常1个 analysis_export(输入)
uvm_agent uvm_component 是 每个协议接口1个 无直接TLM端口
事务对象 uvm_object 否 动态创建 无
常见误区: 不要将 uvm_object 直接作为组件添加到组件树中。所有需要 build_phase、connect_phase 等phase回调的类,必须从 uvm_component 派生。事务对象应通过工厂创建,而非直接 new()。

3.8 本章小结

UVM组件家族为验证环境提供了清晰的层次化架构:

  • uvm_object 和 uvm_component 构成两大基类体系,分别服务于数据对象和硬件组件。
  • uvm_driver、uvm_sequencer、uvm_monitor 和 uvm_scoreboard 是验证环境的核心功能组件。
  • uvm_agent 作为容器组件,封装了特定协议接口的完整驱动与监测能力。
  • 组件之间通过TLM端口实现事务级通信,保证了验证环境的可重用性和可扩展性。