1.重载transaction
class normal_sequence extends uvm_sequence #(my_transaction)
...
virtual task body();
repeat (10) begin
`uvm_do(m_trans)
end
#100;
endtask
`uvm_object_utils(normal_sequence)
endclass
class crc_err_tr extends my_transaction;
…
constraint crc_err_cons{
crc_err == 1;
}
endclass
传统的方法需要一个sequence, 然后将这个sequence作为新的测试用例的default_sequence, 但是有了factory机制的重载功能后, 可以不用重新写一个abnormal_sequence, 而继续使normal_sequence作为新的测试用例 的default_sequence, 只是需要将my_transaction使用crc_err_tr重载。
function void my_case0::build_phase(uvm_phase phase);
super.build_phase(phase);
factory.set_type_override_by_type(my_transaction::get_type(), crc_err_tr::get_type());
uvm_config_db#(uvm_object_wrapper)::set(this,
"env.i_agt.sqr.main_phase",
"default_sequence",
normal_sequence::type_id::get());
endfunction
2.重载sequence
transaction可以重载, 同样的, sequence也可以重载。
class normal_sequence extends uvm_sequence #(my_transaction);
…
virtual task body();
`uvm_do(m_trans)
m_trans.print();
endtask
`uvm_object_utils(normal_sequence)
endclass
class case_sequence extends uvm_sequence #(my_transaction);
…
virtual task body();
normal_sequence nseq;
repeat(10) begin
`uvm_do(nseq)
end
endtask
endclass
这里使用了嵌套的sequence。 case_sequence被作为default_sequence。 现在新建一个测试用例时, 可以依然将case_sequence作为default_sequence, 只需要从normal_sequence派生一个异常的sequence:
class abnormal_sequence extends normal_sequence;
…
virtual task body();
m_trans = new("m_trans");
m_trans.crc_err_cons.constraint_mode(0);
`uvm_rand_send_with(m_trans, {crc_err == 1;})
m_trans.print();
endtask
endclass
function void my_case0::build_phase(uvm_phase phase);
…
factory.set_type_override_by_type(normal_sequence::get_type(), abnorma l_sequence::get_type());
uvm_config_db#(uvm_object_wrapper)::set(this,
"env.i_agt.sqr.main_phase",
"default_sequence",
case_sequence::type_id::get());
endfunction
3.重载component
上面使用重载transaction和重载sequence的方式产生异常的测试用例。 其实,还可以使用重载driver的方式产生。 除了driver可以重载外, scoreboard与参考模型等都可以重载。 尤其对于参考模型来说, 处理异常的激励源是相当耗时的一件事情。 可能对于一个DUT来说, 其80%的代码都是用于处理异常情况, 作为模拟DUT的参考模型来说, 更是如此。 如果将所有的640异常情况都用一个参考模型实现, 那么这个参考模型代码量将会非常大。 但是如果将其分散为数十个参考模型, 每一个处理一种异常情况, 当建立相应异常的测试用例时, 将正常的参考模型由它替换掉。 这样,可使代码清晰,并增加了可读性。 引入sequence的原因是将数据流产生的功能从driver中独立出来。 取消sequence相当于一种倒退, 会使得driver的职能不明确, 与现代编程中模块化、 功能化的趋势不合。 要将所有的测试用例都使用driver重载实现。 只有将driver的重载与sequence相结合, 才UVM的最初设计初衷相符合, 也才能构建起可重用性高的验证平台。
总结
factory机制可以根据类名创建这个类的一个实例; 另外 还可以在创建类的实例时根据是否有重载记录来决定是创建原始的类, 还是创建重载的类的实例。 从本质上来看,factory机制其实是对SystemVerilog中new函数的重载。
参考: UVM实战卷1——张强
|