此处sequence泛指uvm_sequence_item类,item泛指uvm_sequence_item类。
sequence用来实现激励生成和场景控制;item实现对激励所需要的具体数据和控制要求。
sequence item介绍
item基于uvm_object类,具备UVM核心基类所必要的数据操作方法,如copy(),clone(),compare(),record()等。通常将它们划分为以下类:
- 控制类。如总线协议上的读写类型、数据长度、传送模式等。
- 负载类。一般指数据总线上的数据包。
- 配置类。用来控制driver的驱动行为,例如命令driver的发送间隔或者有无错误插入。
- 调试类。用来标记一些额外信息方便调试,例如该对象的实例序号、创建时间、被driver解析的时间始末等。
//实例
class bus_trans extends uvm_sequence item;
rand bit write;
rand int data;
rand int addr;
rand int delay;
static int id_num;
`uvm_object_utils_begin(bus trans)
`uvm_field_int...
`uvm_object_utils_end
...
endclass
class test1 extends uvm_test;
`uvm_component_utils(test1)
...
task run_phase(uvm_phase phase);
bus_trans t1, t2;
phase.raise_objection(phase);
#100ns;
t1 = new("t1");
t1.print;
#200ns;
t2 = new("t2"); //也可使用create进行例化,好处:可以实现override方法;可以建立层次关系。
void`(t2.randomize());
t2.print();
phase.drop_objection(phase);
endtask
endclass
item使用时的特点:
- 如果数据域需要用来做驱动,呢么用户应考虑定义为染得类型,同时按照驱动协议给出合适的constraint。
- 由于item本身的数据属性,为了充分利用UVM域声明的特性,建议将必要的数据成员都通过·uvm_field_xxx宏来声明,以便日后uvm_object的基本数据方法自动实现,例如上面的print()函数。
- t1没有被随机化而t2被随机化了,这种差别在item通往sequencer之前是很明显的。UVM要求item的创建和随机化都发生在sequence的body()任务中,而不是在sequencer或者driver中。
- 按照item对象的生命周期来区分,它的生命应该开始于sequence的body()方法,而后经历了随机化并穿越sequencer最终达到driver,直到被driver消化之后,他的生命一般来讲才结束。要注意在使用时,不能直接操作item对象,直接修改其中的数据,或者将它的句柄发送给其他组件使用,这会无形中修改item的数据,或者延长一个item对象的寿命。正确的方法是合理利用copy()和clone()等数据方法。
item与sequence的关系
一个sequence可以包含一些有序组织起来的item实例,考虑到item在创建后需要被随机化,sequence在声明时也需要预留一些可供外部随机化的变量,这些随机变量一部分是用来通过层级传递约束来最终控