get_reponse和put_response对应。 注意driver中必须有set_id_info函数。 put_response可以省略:需要item_done函数带rsp参数: seq_item_port.item_done(rsp) ----- 但是当有多次rsp的时候,就不能这么用了。 多次的时候只能是调多次get_reponse和put_response
get_response是一个阻塞的task,当sequence没有获取到driver返回的rsp的时候,会阻塞住sequence的body(),所以当driver不能及时返回rsp的时候,get_response??put_response这个机制就有问题了。 UVM的解决方法是使用 response_handler函数:
在pre_body()函数中 use_reponse_handler() 打开这个功能,然后重载response_handler(uvm_sequence_item response)这个函数 ? 一般需要$cast给sequence中的rsp成员 . 而sequence的body task里就不用再调get_response了 6.7.3章节代码示例:
rsp和req的类型可以不同,这个时候注意sequence driver sequencer的参数
6.8 sequence library
sequence library是一系列sequence的结合。 uvm_sequence_library本身是uvm_sequence
的派生类。
实现sequence_library的时候要注意:
1) 在new函数里要增加 init_sequence_library()函数 2) 增加`uvm_sequence_library_utils(类名) 的macro
对于里面的sequence只需要增加一个macro: `uvm_add_to_seq_lib(sequence类名,sequence_library类名)
一个sequence可以加入到不同的sequence_library中
使用sequence_library可以有效简化Testcase,因为case中设置sqr的main_phased的default_sequence是sequence_library类名::type_id::get()
可以使用sequence_library_cfg来控制sequence_library里迭代次数、选择算法以及sequence的个数。但是我觉得使用简化的方法更方便和直观(不用sequence_library_cfg类,而是直接对sequence_library对象的成员赋值):
6.8.4示例代码: 在case的build_phase里实现,需要把sequence_library new出来
第8章 UVM中的factory机制
重点章节 uvm特色
UVM的factory机制也是建立在 systemverilog的
Polymorphism机制上的,所以
function\\task也得是声明成virtual的才行。 使用factory重载的限制:
1) 重载的类和被重载的类,都要在定义的是用uvm_*_util宏来注册
2) 实例化的时候要用::type_id::create(“名字”)的方法 ------- 无论component还是object 3) 重载的类是被重载的类的派生类 4) component和object之间不能重载
重载的方式和种类 注意get_type() 在build_phase中调用
component中的函数:replace参数代表“是否可以被后面的重载覆盖”
set_type_override_by_type(原始类名::get_type(),重载类名::get_type(),replace)
set_inst_override_by_type(相对路径字符串,原始类名::get_type(),重载类名::get_type()) 也可以用类名字符串来代替原始类名::get_type()和重载类名::get_type() set_type_override(原始类名字符串,重载类名字符串,replace)
set_inst_override(相对路径字符串,原始类名字符串,重载类名字符串)
直接使用factory这个全局变量的函数:
与上面的非常类似,只是把“相对路径字符串”变成“绝对路径字符串”,而且移到最后一个参数: initial begin factory.set_inst_override_by_type(my_monitor::get_type(),new_monitor::ge t_type(),”uvm_test_top.env.o_agt.mon”); end
直接使用factory的函数可以放在simv命令里去
simv +uvm_set_inst_override=” my_monitor,new_monitor,uvm_test_top.env.o_agt.mon”
factory机制的调试:
在build_phase后面的phase中调 comp.print_override_info();
factory.debug_create_by_name(); factory.debug_create_byte_type(); factory.print();
uvm_root.print_topolofy();
可以重载 uvm_sequence_item uvm_sequence uvm_component. 都是在case的build_phase中调,而且都是直接用factory的方法
第9章 UVM的代码重用 9.1 callback机制
只给callback机制做了笔记。
uvm的callback和vmm的差不多。 代码步骤如下:
1) 先实现一个uvm_callback的派生类A,以及A的virtual task/function 2) typedef uvm_callbacks#(my_driver,A) A_pool 注意s
3) 在my_driver中注册callback: `uvm_register_cb(my)driver,A) 4) my_driver中使用 `uvm_do_callbacks(my_driver,A,task()) 注意s 5) 从A派生出一个实际用到的类 my_callback , 实现task
6) 在case的connect_phase中实例化my_callback(假设是my_cb),并create它,然后
A_pool::add(my_driver的路径指针,my_cb) -------- 因为my_driver是在main_phase里调callback的,所以要在main_phase前面做这个工作
9.1.4章节示例代码: