The Sequence Library
UVM提供了一个用于随机创建和运行Sequence的类。这个类被称为uvm_sequence_library。uvm_sequence_library类继承自uvm_sequence,这意味着一个Sequence Library的一个实例也是一个Sequence。这一点很重要,因为在配置了Sequence Library之后,就像使用Sequence一样使用它。
不推荐使用Sequence Library,使用前文所描述的方法就能简单的实现激励生成。
uvm_sequence_library类提供了一种从其注册的Sequence列表中随机选择运行Sequence的方法。当Sequence库启动时,运行的Sequence总数是可控的,默认为10个。
创建Sequence库,需要从参数化的uvm_sequence_library类中扩展一个类。可以设置两个参数。它们和Sequence所需的REQ和RSP参数值相同。同样与Sequence一样,RSP默认与REQ相同。
从uvm_sequence_library类扩展后,然后使用`uvm_object_utils()宏进行的工厂注册。然后,需要调用一个唯一的`uvm_sequence_library_utils()宏。宏和函数需要用与Sequence库或其任何基类静态注册的任何Sequence来填充Sequence库
class mem_seq_lib extends uvm_sequence_library #(mem_item);
...
function new(string name="mem_seq_lib");
super.new(name);
//Explicitly add the memory sequences to the library
add_typewide_sequences({mem_seq1::get_type(),
mem_seq2::get_type(),
mem_seq3::get_type(),
mem_seq4::get_type(),
mem_seq5::get_type(),
mem_seq6::get_type()});
endfunction : new
endclass : mem_seq_lib
一般add_typewide_sequence()和/或add_typewide_sequences()是在sequence_library的构造函数中调用。
Sequence也可以通过使用add_sequence()或add_sequences()函数向Sequence库注册。这通常会在实例化Sequence的时候完成。可以使用remove_sequence() API从库中删除Sequence。
class test_seq_lib extends test_base;
...
task main_phase(uvm_phase phase);
phase.raise_objection(this, "Raising Main Objection");
//Register another sequence with this sequence library instance
seq_lib.add_sequence( mem_error_seq::get_type() );
//Start the mem sequence
seq_lib.start(m_mem_sequencer); //This task call is blocking
phase.drop_objection(this, "Dropping Main Objection");
endtask : main_phase
endclass : test_seq_lib
uvm_sequence_library类提供了一些内置的控件,以便在随机化()时约束Sequence库。为了控制Sequence库启动时运行的Sequence数,可以配置min_random_count(默认为10)和max_random_count(默认为10)。
class test_seq_lib extends test_base;
...
task main_phase(uvm_phase phase);
phase.raise_objection(this, "Raising Main Objection");
//Configure the constraints for how many sequences are run
seq_lib.set_min_random_count(5);
seq_lib.set_max_random_count(12);
//Randomize the sequence library
if (!seq_lib.randomize())
`uvm_error(report_id, "The mem_seq_lib library failed to randomize()")
//Start the mem sequence
seq_lib.start(m_mem_sequencer); //This task call is blocking
phase.drop_objection(this, "Dropping Main Objection");
endtask : main_phase
endclass : test_seq_lib
可以在实例化的时候配置或者通过使用uvm_config_db并指定Sequence库的完整路径。后一种方法仅在配置Sequence库为UVM阶段的默认Sequence时使用,而Mentor不推荐它。
还可以控制在Sequence库运行时要执行的下一个Sequence的选择方法,有四个选项。
配置随机化方法,需要在启动Sequence库之前设置selection_mode。
class test_seq_lib extends test_base;
...
task main_phase(uvm_phase phase);
phase.raise_objection(this, "Raising Main Objection");
//Change to RANDC mode for selection
seq_lib.set_selection_mode(UVM_SEQ_LIB_RANDC);
//Start the mem sequence
seq_lib.start(m_mem_sequencer); //This task call is blocking
phase.drop_objection(this, "Dropping Main Objection");
endtask : main_phase
endclass : test_seq_lib