story · 2020年06月12日

数字IC验证系列之Driver&Sequencer

driver的作用是按照接口协议将事务对象驱动到总线。driver从sequencer中获取数据。UVM库提供了uvm\_driver基类,所有的driver类都应该直接或间接地扩展自uvm\_driver。driver有一个run()方法,以及与sequencer通信的TLM端口。

要创建driver:
a)从uvm\_driver基类派生。
b)如果需要,添加UVM基础宏以实现打印,复制,比较等基本方法。
c)从sequencer中获取事务对象。
d)在driver中声明一个虚拟接口,以将driver连接到DUT。

以下示例定义了一个driver类simple\_driver。使用simple\_item事务类型为参数和使用seq\_item\_port方法与sequencer进行通信。包括一个构造函数和\`uvm\_component\_utils宏来注册driver到factory机制。

class simple_driver extends uvm_driver #(simple_item);
 simple_item s_item;
 virtual dut_if vif;
  // UVM automation macros for general components
  `uvm_component_utils(simple_driver)
  // Constructor
  function new (string name = "simple_driver", uvm_component parent);
    super.new(name, parent);
  endfunction : new
  function void build_phase(uvm_phase phase);
    string inst_name;
    super.build_phase(phase);
    if(!uvm_config_db#(virtual dut_if)::get(this,
  “”,"vif",vif))
    `uvm_fatal("NOVIF",
   {"virtual interface must be set for: ",
    get_full_name(),".vif"});
  endfunction : build_phase
  task run_phase(uvm_phase phase);
    forever begin
      // Get the next data item from sequencer (may block).
      seq_item_port.get_next_item(s_item);
      // Execute the item.
      drive_item(s_item);
       seq_item_port.item_done(); // Consume the request.
    end
  endtask : run

 
  task drive_item (input simple_item item);
    ... // Add your logic here.
  endtask : drive_item
endclass : simple_driver

第1行从uvm\_driver基类中派生出driver。
第5行使用UVM基础宏。
第22行调用get\_next\_item()以从sequencer获取下一个要执行的事务对象。
第30行在此处添加特定于driver的逻辑以驱动事务对象。

sequencer生成激励数据并将其传递给driver。UVM库提供uvm\_sequencer基类,该基类包含允许sequencer与driver通信所需的基本功能。如果你需要添加其他功能的话,就需要扩展uvm\_sequencer类。

uvm_sequencer #(simple_item, simple_rsp) sequencer;

driver和sequencer通过TLM连接,sequencer的seq\_item\_port连接到
sequencer的seq\_item\_export,如下图所示。sequencer生成事务对象,driver通过seq\_item\_port使用事务对象。
612.bmp

uvm\_driver中的seq\_item\_port定义了driver用于获取下一个事务对象的方法。

driver和sequencer之间的基本交互是使用任务get\_next\_item()和item\_done()。driver使用get\_next\_item()来获取下一个随机事务。在将其发送到DUT后,driver使用item\_done()向sequencer发出信号。通常,driver中的主循环类似于:

get_next_item(req);
    // Send item following the protocol.
item_done();

get\_next\_item()是阻塞的。

除了get\_next\_item()任务之外,seq\_item \_port类还提供了另一个任务try\_next\_item()。

以下示例使用try\_next\_item(),如果没有实际的事务对象,就会驱动空闲事务:

task run_phase(uvm_phase phase);
 forever begin
 // Try the next data item from sequencer (does not block).
 seq_item_port.try_next_item(s_item);
 if (s_item == null) begin
 // No data item to execute, send an idle transaction.
 ...
 end
 else begin
 // Got a valid item from the sequencer, execute it.
 ...
 // Signal the sequencer; we are done.
 seq_item_port.item_done();
 end
 end
 endtask: run

本文转载自公众号:芯片数字实验室
原文链接:
https://mp.weixin.qq.com/s/zRM8SoYHSuuafL2-\_aVc8w
未经作者同意,请勿转载!

推荐阅读
想了解更多内容,欢迎关注芯片数字实验室专栏
推荐阅读
关注数
12313
内容数
219
前瞻性的眼光,和持之以恒的学习~
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息