uvm transaction

发布于:2025-03-29 ⋅ 阅读:(29) ⋅ 点赞:(0)

UVM Transaction 是验证环境中数据传输的核心单元,用于封装与DUT(Design Under Test)交互的数据和协议信息。它是验证组件(如Driver、Monitor、Scoreboard)之间通信的基础。以下是Transaction的详细解析:


Transaction 的核心作用

  1. 数据封装:将DUT接口的信号(如总线数据、控制信号)抽象为高层次的数据对象。
  2. 组件通信:通过TLM(Transaction Level Modeling)在Driver、Monitor、Scoreboard等组件间传递。
  3. 随机化支持:通过SystemVerilog的随机约束(randconstraint)生成多样化的测试场景。
  4. 功能覆盖:定义覆盖率点(Coverpoint),跟踪关键数据组合。

Transaction 的定义

Transaction通常继承自 uvm_sequence_item 类,需包含以下内容:

1. 数据字段
  • 定义与DUT接口相关的信号(如地址、数据、控制位)。
  • 使用 rand 关键字声明可随机化字段。
class my_transaction extends uvm_sequence_item;
  rand logic [31:0] addr;   // 随机化地址
  rand logic [31:0] data;   // 随机化数据
  rand bit          wr_en;  // 随机化读写使能
  // 其他字段(如协议控制信号)
  ...
  `uvm_object_utils(my_transaction)  // 注册到Factory
endclass
2. 约束(Constraints)
  • 通过 constraint 限制随机化范围,确保生成合法的激励。
class my_transaction extends uvm_sequence_item;
  // 数据字段定义同上
  constraint valid_addr {
    addr inside {[0x0000_0000 : 0xFFFF_FFFF]};  // 地址范围约束
  }
  constraint write_ratio {
    wr_en dist {1 := 70, 0 := 30};  // 70%写操作,30%读操作
  }
endclass
3. 方法(Methods)
  • 可自定义方法用于数据格式化、比对或协议检查。
class my_transaction extends uvm_sequence_item;
  // 数据字段和约束同上

  // 自定义方法:打印事务内容
  function string convert2string();
    return $sformatf("addr=0x%8h, data=0x%8h, wr_en=%0d", addr, data, wr_en);
  endfunction

  // 自定义方法:数据比对
  function bit compare(my_transaction tr);
    return (this.addr == tr.addr) && (this.data == tr.data) && (this.wr_en == tr.wr_en);
  endfunction
endclass

Transaction 的生命周期

  1. 生成(Generation)

    • Sequence 创建并随机化,通过 start_item()finish_item() 发送到Sequencer。
    class my_sequence extends uvm_sequence;
      task body();
        my_transaction tr;
        tr = my_transaction::type_id::create("tr");
        start_item(tr);
        assert(tr.randomize());  // 随机化事务
        finish_item(tr);
      endtask
    endclass
    
  2. 传输(Transfer)

    • Driver 从Sequencer获取Transaction,将其转换为DUT的接口信号。
    class my_driver extends uvm_driver;
      task run_phase(uvm_phase phase);
        forever begin
          seq_item_port.get_next_item(req);  // 获取事务
          vif.drive(req.addr, req.data, req.wr_en);  // 驱动到DUT
          seq_item_port.item_done();
        end
      endtask
    endclass
    
  3. 捕获(Capture)

    • Monitor 从DUT接口捕获信号,重新组装为Transaction并发送给Scoreboard。
    class my_monitor extends uvm_monitor;
      uvm_analysis_port #(my_transaction) analysis_port;
    
      task run_phase(uvm_phase phase);
        forever begin
          @(posedge vif.clk);
          my_transaction tr = my_transaction::type_id::create("tr");
          tr.addr  = vif.addr;  // 捕获地址
          tr.data  = vif.data;  // 捕获数据
          tr.wr_en = vif.wr_en; // 捕获读写使能
          analysis_port.write(tr);  // 发送到Scoreboard
        end
      endtask
    endclass
    
  4. 验证(Validation)

    • Scoreboard 接收Transaction,检查其是否符合预期行为。
    class my_scoreboard extends uvm_scoreboard;
      uvm_analysis_imp #(my_transaction, my_scoreboard) analysis_export;
    
      function void write(my_transaction tr);
        if (tr.wr_en && (tr.data != expected_data))
          `uvm_error("SCB", $sformatf("Data mismatch: Got %0h, Expected %0h", tr.data, expected_data))
      endfunction
    endclass
    

Transaction 的高级特性

1. Factory 机制
  • 动态对象创建:通过 type_id::create() 创建Transaction对象,支持Factory重载。
  • 对象替换:可自定义Transaction子类并覆盖默认类型。
    class debug_transaction extends my_transaction;
      `uvm_object_utils(debug_transaction)
      // 添加调试字段或方法
    endclass
    
    // 在Test中替换默认Transaction类型
    initial begin
      debug_transaction::type_id::set_type_override(my_transaction::get_type());
    end
    
2. 分层Transaction
  • 可继承基类Transaction,扩展出特定协议或场景的子类。
    class axi_transaction extends my_transaction;
      rand logic [3:0] burst_length;  // 新增AXI协议字段
      rand logic [1:0] burst_type;
      constraint valid_burst { burst_length inside {[1:16]}; }
      `uvm_object_utils(axi_transaction)
    endclass
    
3. 协议时序封装
  • 在Transaction中定义时序控制字段(如延迟、握手信号)。
    class my_transaction extends uvm_sequence_item;
      rand int delay_cycles;  // 事务之间的延迟周期
      constraint max_delay { delay_cycles inside {[0:5]}; }
    endclass
    
4. 覆盖率收集
  • 在Transaction中定义覆盖率点(Covergroup)。
    class my_transaction extends uvm_sequence_item;
      covergroup cg;
        coverpoint addr { bins low = {[0:1000]}; bins high = {[1001:$]}; }
        coverpoint data { bins even = {[0:$] with (item % 2 == 0)}; }
        cross addr, data;
      endgroup
    
      function new();
        cg = new();
      endfunction
    
      function void sample();
        cg.sample();  // 在Monitor或Scoreboard中调用
      endfunction
    endclass
    

Transaction 的最佳实践

  1. 原子化设计:每个Transaction对应DUT接口的一次完整操作(如一次总线读写)。
  2. 约束分层:将通用约束定义在基类中,场景特定约束定义在子类中。
  3. 避免过度随机化:约束需确保生成的Transaction符合协议要求。
  4. 复用与扩展:通过继承创建协议特定的Transaction,减少重复代码。

示例:完整的Transaction流程

// 定义Transaction
class packet extends uvm_sequence_item;
  rand logic [7:0]  payload;
  rand logic        error;
  constraint no_error { error == 0; }  // 默认不生成错误

  `uvm_object_utils(packet)
  function new(string name = "packet");
    super.new(name);
  endfunction
endclass

// Sequence生成Transaction
class test_sequence extends uvm_sequence;
  `uvm_object_utils(test_sequence)
  task body();
    packet pkt;
    repeat(10) begin
      pkt = packet::type_id::create("pkt");
      start_item(pkt);
      assert(pkt.randomize());
      finish_item(pkt);
    end
  endtask
endclass

// Driver处理Transaction
class my_driver extends uvm_driver;
  virtual task run_phase(uvm_phase phase);
    packet pkt;
    forever begin
      seq_item_port.get_next_item(pkt);
      `uvm_info("DRV", $sformatf("Driving packet: payload=0x%2h", pkt.payload), UVM_LOW)
      // 驱动到DUT接口...
      seq_item_port.item_done();
    end
  endtask
endclass

总结

UVM Transaction 是验证环境的数据核心,通过封装、随机化和通信机制,实现了高效的测试场景生成和协议验证。合理设计Transaction的结构和约束,能够显著提升验证的灵活性和覆盖率。