3.6 学习UVM中的uvm_sequencer类分为几步?


前言

以下是关于 UVM 中 uvm_sequencer 的详细解释、核心功能、适用场景、使用方法以及一个完整的代码示例:


1. 定义

uvm_sequencer 是 UVM(Universal Verification Methodology)中的一个关键组件类,用于管理事务(transaction)的生成和调度。它与 uvm_driver 配合使用,负责将事务从序列(sequence)传递到 uvm_driver,从而驱动 DUT(Design Under Test)的接口。

uvm_sequencer 的主要特点:

  • 管理事务的生成和调度。
  • uvm_driver 通过 TLM(Transaction Level Modeling)接口通信。
  • 支持多个序列的并行执行和优先级控制。

2. 核心功能

uvm_sequencer 提供了以下核心功能:

  • 事务调度:从序列中获取事务并将其传递给 uvm_driver
  • 序列管理:支持多个序列的启动、停止和优先级控制。
  • 通信接口:通过 seq_item_exportseq_item_portuvm_driver 通信。
  • 仲裁机制:支持多个序列的仲裁,确保事务按预期顺序传递。

3. 适用场景

uvm_sequencer 通常用于以下场景:

  • 事务生成:用于生成和调度事务,驱动 DUT 的接口。
  • 序列控制:管理多个序列的执行顺序和优先级。
  • 复杂激励生成:支持层次化序列和虚拟序列,生成复杂的测试场景。

4. 使用方法

使用 uvm_sequencer 的步骤如下:

  1. 定义类:从 uvm_sequencer 派生一个类(通常直接使用 uvm_sequencer,无需派生)。
  2. 连接 Driver:在 uvm_agent 中将 uvm_sequenceruvm_driver 连接。
  3. 创建序列:定义从 uvm_sequence 派生的序列类,生成事务。
  4. 启动序列:在测试中启动序列,生成事务并传递给 uvm_driver

5. 完整代码示例

以下是一个完整的代码示例,展示如何使用 uvm_sequencer 管理事务的生成和调度。

5.1 事务类定义

// 定义一个从 uvm_sequence_item 派生的事务类
class my_transaction extends uvm_sequence_item;

  rand bit [7:0] data;
  rand bit [3:0] addr;
  bit           valid;

  // 注册类到 UVM 工厂
  `uvm_object_utils(my_transaction)

  // 构造函数
  function new(string name = "my_transaction");
    super.new(name);
  endfunction

  // 实现 print 方法
  virtual function void do_print(uvm_printer printer);
    printer.print_field("data",  this.data,  8);
    printer.print_field("addr",  this.addr,  4);
    printer.print_field("valid", this.valid, 1);
  endfunction

endclass

5.2 Driver 类定义

// 定义一个从 uvm_driver 派生的驱动类
class my_driver extends uvm_driver #(my_transaction);

  // 注册类到 UVM 工厂
  `uvm_component_utils(my_driver)

  // 构造函数
  function new(string name, uvm_component parent);
    super.new(name, parent);
  endfunction

  // 实现 run_phase
  virtual task run_phase(uvm_phase phase);
    forever begin
      my_transaction tx;

      // 从 sequencer 获取事务
      seq_item_port.get_next_item(req);

      // 打印事务
      `uvm_info("DRIVER", $sformatf("Driving transaction: data=0x%0h, addr=0x%0h, valid=%b", 
                                   req.data, req.addr, req.valid), UVM_LOW)

      // 将事务转换为信号激励(这里用延时模拟驱动过程)
      #10;

      // 通知 sequencer 事务处理完成
      seq_item_port.item_done();
    end
  endtask

endclass

5.3 Sequencer 类定义

// 定义一个从 uvm_sequencer 派生的 sequencer 类
class my_sequencer extends uvm_sequencer #(my_transaction);

  // 注册类到 UVM 工厂
  `uvm_component_utils(my_sequencer)

  // 构造函数
  function new(string name, uvm_component parent);
    super.new(name, parent);
  endfunction

endclass

5.4 Sequence 类定义

// 定义一个从 uvm_sequence 派生的序列类
class my_sequence extends uvm_sequence #(my_transaction);

  // 注册类到 UVM 工厂
  `uvm_object_utils(my_sequence)

  // 构造函数
  function new(string name = "my_sequence");
    super.new(name);
  endfunction

  // 实现 body 方法
  virtual task body();
    my_transaction tx;

    // 生成 10 个事务
    for (int i = 0; i < 10; i++) begin
      tx = my_transaction::type_id::create("tx");

      // 随机化事务
      if (!tx.randomize()) `uvm_error("RAND", "Randomization failed")

      // 发送事务到 sequencer
      `uvm_info("SEQUENCE", $sformatf("Generated transaction: data=0x%0h, addr=0x%0h, valid=%b", 
                                     tx.data, tx.addr, tx.valid), UVM_LOW)
      start_item(tx);
      finish_item(tx);
    end
  endtask

endclass

5.5 Agent 类定义

// 定义一个从 uvm_agent 派生的 agent 类
class my_agent extends uvm_agent;

  // 组件句柄
  my_driver    driver;
  my_sequencer sequencer;

  // 注册类到 UVM 工厂
  `uvm_component_utils(my_agent)

  // 构造函数
  function new(string name, uvm_component parent);
    super.new(name, parent);
  endfunction

  // 构建组件
  virtual function void build_phase(uvm_phase phase);
    driver    = my_driver::type_id::create("driver", this);
    sequencer = my_sequencer::type_id::create("sequencer", this);
  endfunction

  // 连接组件
  virtual function void connect_phase(uvm_phase phase);
    driver.seq_item_port.connect(sequencer.seq_item_export);
  endfunction

endclass

5.6 测试平台

// 测试平台
module testbench;
  initial begin
    // 创建 env 类
    class my_env extends uvm_env;
      my_agent agent;

      // 注册类到 UVM 工厂
      `uvm_component_utils(my_env)

      // 构造函数
      function new(string name, uvm_component parent);
        super.new(name, parent);
      endfunction

      // 构建组件
      virtual function void build_phase(uvm_phase phase);
        agent = my_agent::type_id::create("agent", this);
      endfunction
    endclass

    // 创建测试类
    class my_test extends uvm_test;
      my_env env;

      // 注册类到 UVM 工厂
      `uvm_component_utils(my_test)

      // 构造函数
      function new(string name, uvm_component parent);
        super.new(name, parent);
      endfunction

      // 构建组件
      virtual function void build_phase(uvm_phase phase);
        env = my_env::type_id::create("env", this);
      endfunction

      // 运行测试
      virtual task run_phase(uvm_phase phase);
        my_sequence seq;

        phase.raise_objection(this);
        seq = my_sequence::type_id::create("seq");
        seq.start(env.agent.sequencer); // 启动序列
        phase.drop_objection(this);
      endtask
    endclass

    // 启动测试
    initial begin
      run_test("my_test");
    end
  end
endmodule

6. 代码说明

  • 事务类my_transaction 定义了事务的属性和方法。
  • Driver 类my_driver 用于驱动事务到 DUT。
  • Sequencer 类my_sequencer 用于管理事务的调度。
  • Sequence 类my_sequence 用于生成事务并发送到 uvm_sequencer
  • Agent 类my_agent 封装了 uvm_driveruvm_sequencer
  • 测试平台my_envmy_test 类用于构建和运行测试环境。

7. 总结

uvm_sequencer 是 UVM 中用于管理事务生成和调度的关键组件。它与 uvm_driver 配合使用,负责将事务从序列传递到驱动层。通过 uvm_sequencer,可以实现复杂的激励生成和调度,适用于各种验证场景。以上示例展示了如何定义和使用 uvm_sequencer,适用于实际的验证环境。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值