🧪 UVM 语法详解(OOP 视角 · Python 类比版)

目标:理解 UVM 中每个组件“是什么”,而不是“怎么跑测试”。
假设你熟悉 Python 的 class__init__、继承、方法调用。


🧱 1. 类定义与继承

✅ UVM

// 定义一个组件类,继承自 uvm_component
class my_driver extends uvm_component;
  // 类体
endclass

🧠 Python 类比

class MyDriver:
    pass

🔍 说明

  • 所有 UVM 组件必须继承自 uvm_component(或其子类如 uvm_driver, uvm_monitor);
  • 所有事务类(数据包)必须继承自 uvm_objectuvm_sequence_item

🔧 2. 构造函数:new() vs __init__()

✅ UVM

class my_driver extends uvm_component;

  // 构造函数:必须接受 name 和 parent
  function new(string name, uvm_component parent);
    super.new(name, parent); // 调用父类构造器
  endfunction

endclass

🧠 Python 类比

class MyDriver:
    def __init__(self, name, parent):
        self.name = name
        self.parent = parent
        # 父类初始化(Python 中通常自动处理)

⚠️ 注意:UVM 的 new() 不是“创建对象”,而是“初始化已分配的对象”。实际创建由工厂完成(见下文)。


🏷️ 3. 类注册:宏 `uvm_component_utils

✅ UVM

class my_driver extends uvm_component;
  `uvm_component_utils(my_driver)  // ← 关键宏!

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

🧠 Python 类比(模拟注册机制)

# 模拟 UVM 工厂注册表
UVM_FACTORY = {}

def register_class(cls_name, cls):
    UVM_FACTORY[cls_name] = cls

class MyDriver:
    def __init__(self, name, parent):
        self.name = name
        self.parent = parent

# 注册
register_class("MyDriver", MyDriver)

🔍 为什么需要注册?
UVM 使用 工厂模式 动态创建对象。如果不注册,type_id::create() 会失败。


🏭 4. 对象创建:工厂模式 type_id::create()

✅ UVM

// 在 test 或 env 中创建 driver
my_driver drv = my_driver::type_id::create("drv", this);

🧠 Python 类比

# 通过工厂创建(而非直接 MyDriver())
drv = UVM_FACTORY["MyDriver"]("drv", parent=this)

优势:支持运行时替换类(override),实现测试复用。


📦 5. 事务类(数据包):uvm_sequence_item

✅ UVM

class my_item extends uvm_sequence_item;
  `uvm_object_utils(my_item)  // 注意:这里是 object_utils!

  rand bit [7:0] data;   // 随机变量
  rand int delay;

  constraint c_valid {
    data > 8'h10;
    delay inside {[1:10]};
  }

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

🧠 Python 类比

import random

class Transaction:
    def __init__(self, name="Transaction"):
        self.name = name
        # 手动实现约束随机
        self.data = random.randint(0x11, 0xEF)
        self.delay = random.randint(1, 10)

🔍 关键差异

  • UVM:rand + constraint → 编译器/仿真器自动保证合法性;
  • Python:需手动编码,无法表达复杂约束(如 solve beforedist)。

🔄 6. 组件通信:TLM 端口(Port / Export)

✅ UVM(Driver 从 Sequencer 获取事务)

class my_driver extends uvm_driver #(my_item);
  // 内置端口:seq_item_port(类型为 uvm_seq_item_pull_port)
  // 无需声明,基类已提供

  virtual task run_phase(uvm_phase phase);
    forever begin
      seq_item_port.get_next_item(req); // 阻塞等待
      // 驱动 req 到 DUT
      seq_item_port.item_done();        // 通知完成
    end
  endtask
endclass

🧠 Python 类比(简化队列通信)

from queue import Queue

class Sequencer:
    def __init__(self):
        self.queue = Queue()

    def put(self, item):
        self.queue.put(item)

    def get(self):
        return self.queue.get()  # 阻塞

class Driver:
    def __init__(self, sequencer):
        self.sequencer = sequencer

    def run(self):
        while True:
            item = self.sequencer.get()
            self.drive(item)

🔍 UVM 优势

  • 标准化接口(所有 driver 都用 seq_item_port);
  • 类型安全(只能传 my_item);
  • 支持多 producer / single consumer 模型。

📡 7. 发布-订阅:uvm_analysis_port

✅ UVM(Monitor 发布事务)

class my_monitor extends uvm_monitor;
  // 声明分析端口
  uvm_analysis_port #(my_item) ap;

  function new(string name, uvm_component parent);
    super.new(name, parent);
    ap = new("ap", this); // 创建端口实例
  endfunction

  virtual task run_phase(uvm_phase phase);
    forever begin
      my_item item = collect_from_dut();
      ap.write(item); // 发送给所有订阅者
    end
  endtask
endclass

🧠 Python 类比(回调列表)

class Monitor:
    def __init__(self):
        self.subscribers = []

    def subscribe(self, callback):
        self.subscribers.append(callback)

    def run(self):
        while True:
            item = self.collect()
            for cb in self.subscribers:
                cb(item)  # 通知所有监听者

✅ UVM 的 write() 是标准方法,Scoreboard 只需实现 write() 即可接收数据。


🧩 8. 组件组装:build_phaseconnect_phase

✅ UVM

class my_env extends uvm_env;
  my_agent agent;
  my_scoreboard sb;

  virtual function void build_phase(uvm_phase phase);
    // 创建子组件
    agent = my_agent::type_id::create("agent", this);
    sb    = my_scoreboard::type_id::create("sb", this);
  endfunction

  virtual function void connect_phase(uvm_phase phase);
    // 连接通信端口
    agent.monitor.ap.connect(sb.analysis_imp);
  endfunction
endclass

🧠 Python 类比

class Env:
    def __init__(self):
        self.agent = Agent()
        self.scoreboard = Scoreboard()
        # 连接:monitor 的输出 → scoreboard 的输入
        self.agent.monitor.subscribe(self.scoreboard.write)

🔍 UVM 特色

  • build_phase:只负责“创建”,不涉及连接;
  • connect_phase:只负责“连线”,此时所有组件已存在;
  • 两个 phase 由系统自动调用,顺序严格。

✅ 总结:UVM OOP 核心要素对照表

概念 UVM 语法 Python 类比 说明
类定义 class X extends Y; class X(Y): 必须继承 UVM 基类
构造函数 function new(...) def __init__(...) 必须调用 super.new()
类注册 `uvm_component_utils(X) factory.register(X) 工厂创建的前提
对象创建 X::type_id::create(...) Factory.create("X") 支持 override
随机数据 rand + constraint random + while UVM 更强大安全
组件通信 port.connect(export) obj1.callback = obj2.method UVM 标准化、类型安全
组件组装 build_phase / connect_phase __init__ + 手动连线 UVM 自动调度
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐