基本思路
开发一个可重用的UVM验证平台,一般按照如下顺序进行:
- 对数据元素进行建模
- 开发事务级组件
- 开发driver
- 开发sequencer
- 连接driver和sequencer
- 开发monitor
- 例化上述组件
- 开发agent
- 开发env
- 启动场景创建
- 控制仿真结束
- 功能检查并搜集覆盖率
下面就按照这个思路走一遍。
对数据元素进行建模
-
查阅文档,根据数据格式要求进行开发
-
从
uvm_sequence_item
基类中继承 -
定义数据构造器
-
添加控制字来对数据格式进行配置
-
使用UVM 域宏来使能打印、复制、比较等操作
-
定义
do_*
函数来完成产生、比较、打印、压缩和解压缩事务级数据的操作。
另外UVM提供了很多内建函数用来操作数据元素。比如print()
、copy()
、compare()
函数。
为了方便调试和追踪transaction,uvm_transaction
基类提供了get_transaction_id()
成员方法来根据ID进行追踪。此外由于uvm_sequence_item
是从uvm_transaction
继承而来的,因此也可以使用这个方法。
举个简单的例子:
class simple_item extends uvm_sequence_item;
rand int unsigned addr;
rand int unsigned data;
rand int unsigned delay;
constraint c1 { addr < 16'h2000; }
constraint c2 { data < 16'h1000; }
// UVM automation macros for general objects
`uvm_object_utils_begin(simple_item)
`uvm_field_int(addr, UVM_ALL_ON)
`uvm_field_int(data, UVM_ALL_ON)
`uvm_field_int(delay, UVM_ALL_ON)
`uvm_object_utils_end
// Constructor
function new (string name = "simple_item");
super.new(name);
endfunction : new
endclass : simple_item
也可以通过继承来增加更多的约束
class word_aligned_item extends simple_item;
constraint word_aligned_addr { addr[1:0] == 2'b00; }
`uvm_object_utils(word_aligned_item)
// Constructor
function new (string name = "word_aligned_item");
super.new(name);
endfunction : new
endclass : word_aligned_item
可以对数据元素进行控制,比如这里用simple_item_delay_e对delay进行约束控制。
typedef enum {ZERO, SHORT, MEDIUM, LARGE, MAX} simple_item_delay_e;
class simple_item extends uvm_sequence_item;
rand int unsigned addr;
rand int unsigned data;
rand int unsigned delay;
rand simple_item_delay_e delay_kind; // Control field
// UVM automation macros for general objects
`uvm_object_utils_begin(simple_item)
`uvm_field_int(addr, UVM_ALL_ON)
`uvm_field_enum(simple_item_delay_e, delay_kind, UVM_ALL_ON)
`uvm_object_utils_end
constraint delay_order_c { solve delay_kind before delay; }
constraint delay_c {
(delay_kind == ZERO) -> delay == 0;
(delay_kind == SHORT) -> delay inside { [1:10] };
(delay_kind == MEDIUM) -> delay inside { [11:99] };
(delay_kind == LARGE) -> delay inside { [100:999] };
(delay_kind == MAX ) -> delay == 1000;
delay >=0; delay <= 1000; }
endclass : simple_item
开发事务级组件
简化了的典型的事务级验证平台如下图所示:

- sequencer产生transaction给driver
- driver用于将transaction转为可用信号给DUT
- monitor收集DUT接口上的信号并转换成transaction
- 分析组件如覆盖率收集或者记分板用于对transaction进行分析
其实可以像下图这样使用agent在更高抽象级上对组件进行封装和配置,从而提高验证平台的可重用性。
开发driver
driver的作用是将数据元素根据接口协议驱动到总线,其数据是从driver处获得的。
开发一个driver即:
- 从
uvm_driver
中继承 - 如果需要的话,可以使用UVM宏来实现打印、复制、比较等操作
- 从sequencer中获取数据元素并转为符合接口协议的总线信号
- 声明一个虚拟接口连接到DUT
class simple_driver extends uvm_driver #(simple_item);
simple_item s_item;
virtual dut_if vif;
// UVM