其他分享
首页 > 其他分享> > 什么是UVM?UVM由哪些组件构成?

什么是UVM?UVM由哪些组件构成?

作者:互联网

一、什么是UVM?

UVM是一种为开发testbench而设计的事物级建模(TLM)方法。

从编程语言的角度来说,UVM是一个类库,可以比较方便的编写可重用可配置的代码。

从某种意义上来说,一旦您使用UVM类库将所需要的代码组织在一起,就可以重用,可以将其带到下一个项目。只有driver ( in UVM agent ), scoreboard, 以及基本的transaction 和 sequence 需要改。如果使用纯SystemVerilog, TestBench是临时编写的,因为sv编写测试台没有特别的编码标准,所以这些测试台就不是完全可重用的,代码也难以理解和维护。

UVM 是基于类的,并通过事务(transaction)在这些类之间进行通信。这有助于将类components之间的通信接口与 UVM agent driver中的实现细节分开。

 

UVM层次架构:

下图显示了一个简单的层次架构(图片来自 ASIC&SoC Functional Design Verification  A Comprehensive Guide to Technologies and Methodologies (Mehta, Ashok B))

 

以下组件构成了UVM的架构

UVM Testbench

UVM Test

UVM Environment

UVM agent

Top level(UVM Testbench)包含一个或多个UVM Enviroments。每个UVM Enviroments都包含一个用于特定 DUT interface的agent。环境可能包含scoreboard。scoreboard将输出与预期输出进行比较。

UVM agent由sequencer、driver 和 monitor组成。

 

二、从高层次上看每个组件:

UVM TestBench

UVM 测试平台通常会实例化被测设计 (DUT) 模块和 UVM 测试类,并配置(configdb类)它们之间的连接。UVM 中的 TLM 类(接口)提供了一组一致的通信方法,用于在组件之间发送和接收事务。组件本身在TestBench中被实例化和连接,以执行验证设计所需要的不同操作。

需要注意的是,UVM Test是在运行时动态实例化的,允许 UVM TestBench编译一次并运行许多不同的Test。

如下图所示,事物级(transaction level)UVM testbench 实例化了DUT和驱动DUT 的agent。agent由driver,sequencer,monitor组成。还实例化了用于分析数据的scoreboard。这是一个最基本的testbench。

该测试平台包含的组件:

 1.  sequencer, 生成 transaction-level item 提供给driver。
 2. driver, 从sequencer主动获取事物(transaction 也叫 item),然后转换为引脚信号去驱动DUT。

 3. monitor,监听引脚信号级数据,然后将其转换回transaction级数据,提供给scoreboard。
 4. scoreboard,从monitor获取transaction数据,然后与预期transaction对比(由reference model 产出)。

 

UVM Test

UVM Test 是UVM TestBench的最高层组件。Test是一个类,它封装了验证人员准对某个特定功能写的测试内容。

UVM Test通常:

1. 实例化uvm_env。

2. 配置环境(通过工厂覆盖或配置类(其实是个数据库))。

3. 通过env调用 UVM sequence向 DUT 施加激励。

通常,有一个带有 UVM 环境实例化和其他常见项目的base uvm test。个别test将扩展base test并以不同方式配置环境或选择不同的sequence来运行。

 UVM Environment

UVM environment 是将其他相互关联的验证组件组合在一起的验证组件。通常在uvm_env中例化的组件包括UVM agents, UVM scoreboard,甚至其他的uvm_env。顶层的UVM Environment封装了所有验证DUT需要用到的组件。

顶级 UVM 环境可以实例化其他 UVM 环境。通常,对于 DUT 的每个接口都有一个单独的环境。例如,PCIe 环境、USB 环境等。其中一些 IP 环境可以组合成集群环境(例如,IP 接口环境、CPU 环境等)。

UVM agent

UVM agent是一个分层组件,它将处理特定 DUT 接口的其他验证组件组合在一起。 Agent 包括一个用于管理激励的 UVM sequencer、一个用于向 DUT 接口施加激励的 UVM driver以及一个用于监控 DUT 接口的 UVM monitor。 如下图所示:

 

请注意,agent可以在主动模式或被动模式下运行。在主动模式下,它可以产生激励(即driver驱动 DUT 输入并检测 DUT 输出)。在被动模式下,驱动程序和sequencer保持沉默(禁用),只有monitor保持活动状态。 Monitor 只是监控 DUT 的输出;它无法控制 DUT 的 IO。您可以在主动模式或被动模式下动态配置agent。 从上图可知,monitor是一个单向接口,而driver是一个双向接口。

UVM Sequence Item

uvm_sequence_item 是UVM层次结构中最基本的对象。他是基本事物(transaction)的顶底。uvm_sequence_item 定义基本transaction(如 AXI transaction)的数据项 和 约束(constraint)。虽然driver是将比特级别的信号驱动到DUT,但是当远离DUT的时候,保持比特级别的抽象没有意义,所以创造了事物级别的抽象。

也就是说,事务(transaction)是可以在验证模型中传输的最小数据单元。它可以包括变量(数据)、约束,甚至是对其自身进行操作的方法。

看一个例子, uvm_sequence_item的定义:

class lpi_seq_item extends uvm_sequence_item;
         ùvm_object_utils(lpi_seq_item)
         //Data members
         rand bit      slp_req0;
         rand bit      slp_req1;
         rand bit      wakeup_req0;
         rand bit      wakeup_req1;
         rand bit      ss_wakeup;
         rand bit      ss_sleep;
         //UVM Constructor
         function new (string name="lpi_seq_item");
         super.new (name);
         endfunction
         //constraints on data members
         constraint slp_wakeup_reqs { (((slp_req0 || slp_req1) && (wakeup_req0 || wakeup_req1)) != 1); };
endclass: lpi_seq_item

 

 UVM Sequence

创建基本 uvm_sequence_item 后,验证环境需要使用item生成序列并发送到sequencer。Sequences是transaction(sequence items)的有序集合,Sequence可以按照需求塑造transactions,并且需要多少就可以产生多少。

Sequence的主要作用就是生成多个transaction。在生成这些transaction之后,还有另一个类将它们带到sequence。

 看个书中例子:

class lpi_basic_seq extends uvm_sequence #(lpi_seq_item);
         `uvm_object_utils(lpi_basic_seq)
         rand int num_of_trans;
         function new (string name="lpi_basic_seq");
           super.new (name);
          endfunction
          extern task body();
endclass: lpi_basic_seq
task lpi_basic_seq::body();
         lpi_seq_item seq_item;
         seq_item = lpi_seq_item::type_id::create("seq_item");
         for (int i = 0; i < num_of_trans; i++)
           begin
            `uvm_info(get_type_name(),$psprintf("in seq for count = %d", i, ,UVM_LOW)
            start_item(seq_item);
            if(!seq_item.randomize())
             begin
               `uvm_error("body","Randomization failed for seq_item")
             end
             `uvm_info(get_type_name(),$psprintf("obj is req0 = %d, req1 = %d, sleep0 = %d, sleep1 =%d", seq_item.wakeup_req0, seq_item.wakeup_req1, seq_item.slp_req0, seq_item.slp_req1) ,UVM_LOW)
             finish_item(seq_item);
           end
endtask: body

 这段代码这个英文解释非常通俗易懂

UVM Sequencer

sequencer控制着driver与sequence之间的 item 的请求与响应。它就像一个仲裁器控制着来自多个sequence的item流。

sequencer 和 driver 使用 TLM 接口 进行通信。

uvm_sequencer 和 uvm_driver base classes 分别定义了 seq_item_export 和 seq_item_port,用户需要使用 TLM 连接方法连接它们。示例:driver.seq_item_port.connect(sequencer.seq_item_export);

----------待补充-----------------

标签:transaction,seq,哪些,item,UVM,组件,DUT,uvm
来源: https://www.cnblogs.com/fuqiangblog/p/16599600.html