uvm-1.2源码学习
?声明:
- 作者主页:【MangoPapa的CSDN主页】。
- ?? 本文首发于CSDN,转载或引用请注明出处【点击查看原文】。
- ?? 本文为非盈利性质,目的为 个人学习记录 及 知识分享。因个人能力受限,存在协议解读不正确的可能。若您参考本文进行产品设计或进行其他事项并造成了不良后果,本人不承担相关法律责任。
- ?? 若本文所采用图片或相关引用侵犯了您的合法权益,请联系我进行删除。
- 欢迎大家指出文章错误,欢迎同行与我交流 ~
- 邮箱:mangopapa@yeah.net
文章目录
- uvm-1.2源码学习
- 前言
- ? uvm-1.2/src/ 顶层文件
-
- ? README.txt
-
- ? 如何安装UVM包
- ? 如何使用UVM
- ? 如何运行测试用例
- ? LICENSE.txt
- ? release-notes.txt
- ? uvm_checksum.txt
- ? uvm.sv
- ? uvm_pkg.sv
- ? uvm_macros.svh
- ? uvm_vmm_pkg.sv
- ? uvm_asm.sv
- ? macros
-
- ? uvm_callback_defines.svh
- ? uvm_deprecated_defines.svh
- ? uvm_global_defines.svh
- ? uvm_message_defines.svh
- ? uvm_object_defines.svh
- ? uvm_phase_defines.svh
- ? uvm_printer_defines.svh
- ? uvm_reg_defines.svh
- ? uvm_sequence_defines.svh
- ? uvm_tlm_defines.svh
- ? uvm_undefineall.svh
- ? uvm_version_defines.svh
- ? base
-
- ? uvm_globals.svh
- ? uvm_object_globals.svh
- ? uvm_object.svh
- ? uvm_event.svh
- ? uvm_event_callback.svh
- ? uvm_barrier.svh
- ? uvm_coreservice.svh
- ? uvm_cmdline_processor.svh
- ? uvm_resource.svh
- ? uvm_resource_db.svh
- ? uvm_resource_specializations.svh
- ? uvm_packer.svh
- ? uvm_queue.svh
- ? uvm_spell_chkr.svh
- ? uvm_pool.svh
- ? uvm_links.svh
- ? uvm_comparer.svh
- ? uvm_misc.svh
- ? uvm_heartbeat.svh
- ? uvm_registry.svh
- ? uvm_recorder.svh
- ? uvm_report_server .svh
- ? comps
-
- ? uvm_comps.svh
- ? uvm_env.svh
- ? uvm_agent.svh
- ? uvm_driver.svh
- ? uvm_push_driver.svh
- ? uvm_monitor.svh
- ? uvm_test.svh
- ? uvm_scoreboard.svh
- ? uvm_random_stimulus.svh
- ? uvm_in_order_comparator.svh
- ? uvm_algorithmic_comparator.svh
- ? uvm_policies.svh
- ?seq
-
- ? uvm_seq.svh
- ? uvm_sequence_item.svh
- ? uvm_sequence_base.svh
- ? uvm_sequence.svh
- ? uvm_sequence_builtin.svh
- ? uvm_sequence_library.svh
- ? uvm_sequencer_base.svh
- ? uvm_sequencer_param_base.svh
- ? uvm_sequencer.svh
- ? uvm_push_sequencer.svh
- ? uvm_sequencer_analysis_fifo.svh
- ? direct
-
- ? uvm_direct.svh
- ? uvm_seed.vh
- ? dap
-
- ? uvm_dap.svh
- ? uvm_set_get_dap_base.svh
- ? uvm_simple_lock_dap.svh
- ? uvm_set_before_get_dap.svh
- ? uvm_get_to_lock_dap.svh
- ? include
-
- ? snps_reg_uints.h
- ? pureC
-
- ? snps_reg_rw_api.h
- ? uvmC
-
- ? snps_reg_rw_api.h
- ? dpi
-
- ? uvm_dpi.cc
- ? uvm_dpi.h
- ? uvm_dpi.svh
- ? uvm_common.c
- ? uvm_hdl.c
- ? uvm_hdl.svh
- ? uvm_hdl_inca.c
- ? uvm_hdl_questa.c
- ? uvm_hdl_vcs.c
- ? uvm_regex.svh
- ? uvm_regex.cc
- ? uvm_svcmd_dpi.svh
- ? uvm_svcmd_dpi.c
- ? deprecated
-
- ? readme.important
- ? uvm_resource_converter.svh
- ? 总结
前言 ??近期比较闲,终于可以系统性地看下uvm源码了,边看边做笔记记在这里。平时用uvm-1.2比较多,本文也是针对uvm-1.2源码进行review。
? uvm-1.2/src/ 顶层文件 ? README.txt ??上来便是四家联合声明版权,然后才有以下内容。
? 如何安装UVM包
?? 1. 在合适的位置新建文件夹,mkdir uvm1.2
?? 2. 进入文件夹,cd uvm1.2
?? 3. 解压缩到当前文件夹,gunzip –c tar.gz | tar xvf –
?? 4. 设置环境变量$UVM_HOME指向该文件夹,setenv UVM_HOME /uvm1.2
?? 5. 其他system verilog 版本适配问题 。。。
? 如何使用UVM
?? 1. 前提条件:① 符合IEEE1800标准的SV仿真器;② 兼容gmake的make以执行基于Makefile的用例;③ C编译器以编译DPI代码
?? 2. 编译命令行中+include+ 、$UVM_HOME把UVM路径include进来
?? 3. 应在最开始就编译uvm.sv
?? 4. 在sv code中导入uvm包,import uvm_pkg:: *;
?? 5. `include “uvm_macros.svh”以使用uvm宏;
?? 6. 如有必要,还需编译/uvm-1.2/dpi/uvm_dpi.cc或指定UVM DPI共享库
? 如何运行测试用例
?? 1. cd example
?? 2. 执行make –f Makefile.{ius|vcs|questa},具体看你使用的哪种仿真器
? LICENSE.txt ?? 这个就没必要介绍了,文本里没有秘钥,是关于秘钥的解释说明。
? release-notes.txt ?? 发版纪要,记录了版本迭代的点点滴滴,有兴趣可以看下。
? uvm_checksum.txt ?? uvm校验和,具体用途待考究,猜测是跟licence搭配使用的?还是说验证用户编程规范性用的?
? uvm.sv ?? 这就是需要放在最开始编译的文件,本文件里include uvm_pkg.sv,如果define了VCS,再把vcs/snps_reg.svh include进来
? uvm_pkg.sv ??uvm_pkg就是在这里封装的哦,package里封装了以下必选项:dpi/base/dap/tlm1/tlm2/comps/seq/reg,要使用directc及vcs目录下文件的话,需define指定宏。direct/vcs具体作用下文专门介绍。
??本文件中、package外部include了uvm_macros.svh,所以其他地方可以免去该步操作。
? uvm_macros.svh ??uvm_macros.svh里包含了所有UVM的宏定义。宏的作用、优劣就不介绍了。本文件除了把$UVM_HOME/src/macros/下的svh include进来,还定义了一些其他宏,比如UVM_USE_STRING_QUEUE_STREAMING_PACK、uvm_typename(X)、uvm_delay(TIME)及verdi、vcs控制相关的宏。
? uvm_vmm_pkg.sv ??重定向vmm message到uvm message、给vmm env重新包了一层wrap到uvm env等。
? uvm_asm.sv ??UVM-AMS工作组制定的一些标准都再这个文件里了,是些模拟和数字系统建模用到的东西。AMS全称是analog/mixed-signal extension for the universal verification methodology,致力于模拟和混合信号建模。UVM-AMS介绍链接。内容还是挺丰富的,此处仅简单罗列部分内容:① 数学系统相关 - 定义了数学常量PI、三角函数、取指取对求根德数学运算、求bessel值(DPI-C实现),real与int类型互相转换;② 模拟相关 - 定义了电压、电流、频率时间的枚举类型,且可以获取给定单位的尺度因子,设置/获取电压、电流、频率、阈值、窗口、checker等。
? macros ??没错,uvm所有宏相关的东西都在这儿了。
? uvm_callback_defines.svh ??uvm_callback相关的宏:
·uvm_register_cb - 调用uvm_callbacks类来注册callback? uvm_deprecated_defines.svh ??以下宏不建议使用:
·uvm_set_super_type - 调用uvm_derived_callbacks来设置超级类型
·uvm_do_obj_callbacks - 不解释,不会接受
·uvm_do_callbacks - 调用宏`uvm_do_obj_callbacks实现callback
·uvm_do_obj_callbacks_exit_on
·uvm_do_callbacks_exit_on - 调用` uvm_do_obj_callbacks_exit_on
·m_uvm_register_sequence? uvm_global_defines.svh ??UVM全局宏,主要有3个,UVM_MAX_STREAMBITS(4096)、UVM_PACKER_MAX_BYTES(4096)及超时退出默认值UVM_DEFAULT_TIMEOUT(9200s)
·uvm_sequence_utils
·uvm_sequence_utils_begin
·uvm_sequence_utils_end
·uvm_declare_sequence_lib
·uvm_update_sequence_lib
·uvm_update_sequence_lib_and_item
·uvm_sequencer_utils
·uvm_sequencer_utils_begin
·uvm_sequencer_utils_end
·uvm_sequencer_param_utils
·uvm_sequencer_ param_utils_begin
·uvm_sequencer_ param_utils_end
·uvm_package
·uvm_end_package
·uvm_sequence_library_package
? uvm_message_defines.svh ??uvm打印信息相关的宏,常用的`uvm_info/warning/error/fatal等都在这里进行了定义,通过调用uvm_report_info/warning/error/fatal等函数实现打印。打印之前会进行判断,只有符合冗余度阈值条件的才会打印。只有`uvm_info需要手动设置冗余度,`uvm_warning/error/fatal的冗余度都是UVM_NONE,无需设置,若要关闭相关打印,可以在仿真选项sim_opts里关闭其action(+uvm_set_action=…UVM_NO_ACTION)。如果某些打印信息不方便在code中直接改冗余度,可以通过+uvm_set_verbosity选项重载其打印冗余度。
??uvm_info_context、uvm_warning_context、uvm_error_context、uvm_fatal_context这四个宏的作用跟uvm_info、uvm_warning、uvm_error、uvm_fatal的作用相同,只是多了一个参数,需要指定对象,执行指定对象的相关函数(uvm_report_enable
& uvm_report_*),例如uvm_info_context(“main_phase”,”run main phase”, UVM_LOW, tb_top),执行tb_top里的uvm_report_enable 和
uvm_report_info函数,而不是到uvm_pool中去调。
??此外还有uvm_message_begin、uvm_message_end、uvm_message_context_begin、uvm_message_context_end,其用途是uvm library内部使用,没有形成规范,也不对外开放。
??与之对应的,还有uvm_info_begin、uvm_info_end、uvm_warning_begin、uvm_warning_end、uvm_error_begin、uvm_error_end、uvm_fatal_begin、uvm_fatal_end、uvm_info_context_begin、uvm_info_context_end、uvm_warning_context_begin、uvm_warning_context_end、uvm_error_context_begin、uvm_error_context_end、uvm_fatal_context_begin、uvm_fatal_context_end,这些也是不建议使用。
??uvm message机制支持用户定制信息,通过uvm_message_add_int、uvm_message_add_string、uvm_message_add_tag、uvm_message_add_object实现定制。这几个平时我没用过,猜测啊,这些还要搭配uvm_info_begin/end来使用。
??仿真时加宏UVM_REPORT_DISABLE_FILE_LINE、UVM_REPORT_DISABLE_FILE、UVM_REPORT_DISABLE_LINE来选择控制关闭打印文件信息和(或)行号信息。
? uvm_object_defines.svh ??只有用uvm__utils宏注册过的component/onject,才能使用uvm factory机制的在check_fields、copy、compare、pack、unpack、record、print、setint方面提供的便利,建议仔细看看啊,还是很有意思的,由于宏太多就不一一讲了。相关的宏都列这儿啦。
? uvm_field_utils_begin(T)??以上宏定义调用到的宏
? uvm_field_utils_end,end+endfunction
? uvm_object_utils(T),是以下两个宏的封装
??uvm_object_utils_begin
??uvm_object_utils_end
? uvm_object_utils_begin(T) ,是以下四个宏的封装
??m_uvm_object_registry_internal(T,T)
??m_uvm_object_create_func(T)
??m_uvm_get_type_name_func(T)
??uvm_field_utils_begin(T)
? uvm_object_utils_end
? uvm_object_param_utils(T)
? uvm_object_param_utils_begin(T)
? uvm_component_utils(T)
? uvm_component_param_utils(T)
? uvm_component_utils_begin(T)
? uvm_component_param_utils_begin(T)
? uvm_component_utils_end
? uvm_field_int(ARG,FLAG)
? uvm_field_real(ARG,FLAG)
? uvm_field_enum(T,ARG,FLAG)
? uvm_field_object(ARG,FLAG)
? uvm_field_event(ARG,FLAG)
? uvm_field_string(ARG,FLAG)
? uvm_field_array_enum(ARG,FLAG)
? uvm_field_array_int(ARG,FLAG)
? uvm_field_sarray_int(ARG,FLAG)
? uvm_field_sarray_enum(ARG,FLAG)
? uvm_field_array_object(ARG,FLAG)
? uvm_field_sarray_object(ARG,FLAG)
? uvm_field_array_string(ARG,FLAG)
? uvm_field_sarray_string(ARG,FLAG)
? uvm_field_queue_enum(ARG,FLAG)
? uvm_field_queue_int(ARG,FLAG)
? uvm_field_queue_object(ARG,FLAG)
? uvm_field_queue_string(ARG,FLAG)
? uvm_field_aa_int_string(ARG, FLAG)
? uvm_field_aa_string_string(ARG, FLAG)
? uvm_field_aa_object_string(ARG, FLAG)
? uvm_field_aa_int_int(ARG, FLAG)
? uvm_field_aa_int_int(ARG, FLAG)
? uvm_field_aa_int_int_unsigned(ARG, FLAG)
? uvm_field_aa_int_integer(ARG, FLAG)
? uvm_field_aa_int_integer_unsigned(ARG, FLAG)
? uvm_field_aa_int_byte(ARG, FLAG)
? uvm_field_aa_int_byte_unsigned(ARG, FLAG)
? uvm_field_aa_int_shortint(ARG, FLAG)
? uvm_field_aa_int_shortint_unsigned(ARG, FLAG)
? uvm_field_aa_int_longint(ARG, FLAG)
? uvm_field_aa_int_longint_unsigned(ARG, FLAG)
? uvm_field_aa_int_key(KEY, ARG, FLAG)
? uvm_field_aa_string_int(ARG, FLAG)
? uvm_field_aa_object_int(ARG, FLAG)
? m_uvm_object_create_func(T)??除了上边提到的宏之外,还有一些杂散的宏,写代码的时候可以调用
? m_uvm_get_type_name_func(T)
? m_uvm_object_registry_internal(T, S)
? m_uvm_object_registry_param(T)
? m_uvm_component_registry_internal(T, S)
? m_uvm_ component_registry_param(T)
? M_UVM_QUEUE_RESIZE
? M_UVM_ARRAY_RESIZE
? M_UVM_SARRAY_RESIZE
? M_UVM_FIELD_QDA_INT
? M_UVM_FIELD_QDA_OBJECT
? M_UVM_FIELD_QDA_STRING
? M_FIELD_QDA_ENUM
? m_uvm_print_int
? m_uvm_record_int
? m_uvm_record_string
? m_uvm_record_object
? m_uvm_record_qda_int
? m_uvm_record_qda_enum
? m_uvm_record_qda_object
? m_uvm_record_qda_string
? M_UVM_FIELD_DATA_AA_generic
? M_UVM_FIELD_DATA_AA_int_key
? M_UVM_FIELD_DATA_AA_int_string
? M_UVM_FIELD_DATA_AA_enum_key
? M_UVM_FIELD_DATA_AA_object_string
? M_UVM_FIELD_DATA_AA_object_int
? M_UVM_FIELD_DATA_AA_string_string
? M_UVM_FIELD_SET_AA_TYPE
? M_UVM_FIELD_SET_AA_OBJECT_TYPE
? M_UVM_FIELD_SET_AA_INT_TYPE
? M_UVM_FIELD_SET_AA_INT_ENUMTYPE
? uvm_new_func,实现function new,但name和parent传不进来? uvm_phase_defines.svh ??文件描述写得很明白了,这个文件中的define是给uvm_root.svh用的,用以简单创建所有的phase。这些宏仅能够创建uvm内建的phase,因为其实从uvm_component来的,不支持自定义的phase。如果需要实现更复杂的phase,用户可以从uvm_task/topdown/bottomup_phase基类中派生出新的类,然后细化一下exec_task或exec_func就可以啦。
? uvm_record_attribute
? uvm_record_int
? uvm_record_string
? uvm_record_time
? uvm_record_real
? uvm_record_field
? uvm_pack_int
? uvm_pack_string
? uvm_pack_real
? uvm_pack_array
? uvm_pack_queue
? uvm_pack_sarray
? uvm_pack_enum
? uvm_pack_enumN
? uvm_pack_intN
? uvm_pack_sarrayN
? uvm_pack_arrayN
? uvm_pack_queueN
? uvm_unpack_queue
? uvm_unpack_array
? uvm_unpack_sarary
? uvm_unpack_real
? uvm_unpack_string
? uvm_unpack_enum
? uvm_unpack_int
? uvm_unpack_queueN
? uvm_unpack_arrayN
? uvm_unpack_sararyN
? uvm_unpack_enum
? uvm_unpack_int
??m_uvm_task_phase实现了一个直接扩展自uvm_task_phase的类,详情可查看base/uvm_task_phase.svh的解读。
【UVM|UVM源码解读,UVM-1.2 code review notes】??m_uvm_bottomup_phase实现了一个直接扩展自uvm_bottomup_phase的类,m_uvm_topdown_phase实现了一个直接扩展自uvm_topdown_phase的类,两者里边比较简单,实现了new和get_type_name两个函数。除了父类不一样外,两者唯一的不同,就在于m_uvm_topdown_phase这个宏在例化phase的时候,类型是local的,bottomup没有特意指明local。
??在m_uvm_bottomup_phase和m_uvm_updown_phase基础上再包一层,有了uvm_buildin_task_phase、uvm_buildin_topdown_phase、uvm_buildin_bottomup_phase,三个参数中只有PHASE一个参数是变量,COMP=uvm_component,PREFIX=uvm_。未方便用户使用,继续放开,便有了uvm_user_task_phase、uvm_user_topdown_phase、uvm_user_bottomup_phase,PHASE、COMP、PREFIX三个参数都由用户指定。
? uvm_printer_defines.svh ??提供了一系列printing相关的宏,自己去看吧。
? uvm_reg_defines.svh ??定义了uvm寄存器地址位宽UVM_REG_ADDR_WIDTH(64)、数据位宽UVM_REG_DATA_WIDTH(64)、Byte位宽UVM_REG_BYTENABLE_WIDTH((64-1)/8+1)、coverage
model set最大比特数UVM_REG_CVR_WIDTH(32)。
? uvm_sequence_defines.svh ??uvm sequence相关的宏都再这儿了。记得uvm_sequence里用到的uvm_do、uvm_do_on、uvm_do_with、uvm_send之类的宏不,就在这里,简单列在这里:
? uvm_tlm_defines.svh ??tlm imp接口声明系列宏:
- uvm_create, 在m_sequencer上创建指定的sequence或item
- uvm_create_on,与uvm_create作用相同,用户可指定sequencer创建sequence或item
- uvm_do,默认采用m_sequencer发送transaction,优先级默认为-1。如果在sequence上create,这个宏相当于以下几步:
① uvm_create(sub_seq)
② sub_seq.randomize()
③ this.pre_start()
④ this.pre_do(0)
⑤ this.mid_do(sub_seq)
⑥ sub_seq.body()
⑦ this.post_do(sub_seq)
⑧ sub_seq.post_start()
如果在sequence item上create,这个宏相当于以下几步:
① sequencer.wait_for_grant(prior)
② this.pre_do(0)
③ item.randomize()
④ this.mid_do(item)
⑤ sequencer.send_request(item)
⑥ sequencer.wait_for_item_done()
⑦ this.post_do(item)- uvm_do_pri,与uvm_do作用相同,用户可指定sequence的执行优先级
- uvm_do_on,与uvm_do作用相同,用户可指定sequencer创建sequence或item
- uvm_do_on_pri,与uvm_do作用相同,用户可指定sequencer创建sequence及指定sequence的执行优先级
- uvm_do_with,与uvm_do作用相同,用户可指定约束条件
- uvm_do_on_with,与uvm_do_on作用相同,用户可指定sequencer创建sequence
- uvm_do_pri_with,与uvm_do_with作用相同,用户可指定sequence执行的优先级
- uvm_do_on_pri_with,与uvm_do_pri_with作用相同,用户可指定sequencer创建sequence。其实,所有uvm_do相关的宏都是直接或间接调用了uvm_do_on_pri_with这个宏,只是把一些参数固定死了。
- uvm_send,发送sequence或item,调用了uvm_sequence_pri,优先级-1
- uvm_send_pri,发送sequence或item,用户指定优先级;先判断是否为sequence,如果不是,start_item然后finish_item;如果是,则启动sequence。在使用uvm_send*之前,要先uvm_create
- uvm_rand_send
- uvm_rand_send_pri
- uvm_rand_send_with
- uvm_rand_send_pri_with,所有uvm_rand_send*相关的宏都是直接或间接调用自uvm_rand_send_pri_with。其跟uvm_do*系列宏的区别就在于uvm_send需提前uvm_create。其跟uvm_send*系列宏的区别在于,uvm_rand_send*会对sequence/item进行判断,如果sequence/ietm为空或随机失败,报uvm_warning。
- uvm_create_seq,跟uvm_create_on作用类似,uvm_create_seq(seq,
sqr)相当于uvm_create_on(seq,
sqr.consumer_seqr),consumer_seqr需要用户在自己sequencer中定义。- uvm_do_seq,同上
- uvm_do_seq_with,同上
- uvm_add_to_seq_lib,静态添加sequence到sequence lib
- uvm_sequence_library_utils
- uvm_declare_p_sequencer,声明p_sequencer并强制转换为m_sequencer类型
? uvm_undefineall.svh ??本文件用以解除所有uvm库自己define的宏,这样单次编译就能load到多个scope中。(恕我资浅,没看懂啥意思,原文附上:This
- uvm_blocking_put_imp_decl,声明一个blocking_put_img类,从uvm_port_base扩展而来,实现了一个put的task,task put无返回值
- uvm_nonblocking_put_imp_decl,声明一个nonblocking_put_img类,从uvm_port_base扩展而来,实现了一个try_put和can_put的task,try_put_*成功返回1,失败返回0
- uvm_put_imp_decl,声明一个put_img类,实现了put、try_put和can_put
- uvm_blocking_get_imp_decl,声明一个blocking_get_img类,从uvm_port_base扩展而来,实现了一个get的task,task get无返回值
- uvm_nonblocking_get_imp_decl,声明一个nonblocking_get_img类,从uvm_port_base扩展而来,实现了一个try_get和can_get的task,try_get_*成功返回1,失败返回0
- uvm_get_imp_decl,声明一个get_img类,实现了get、try_get和can_get
- uvm_blocking_peek_img_decl,跟get_imp的区别在于,peek是主动获取
- uvm_nonblocking_peek_img_decl
- uvm_peek_img_decl
- uvm_blocking_get_peek_img_decl,get_img+peek_img
- uvm_nonblocking_get_peek_img_decl
- uvm_get_peek_img_decl
- uvm_blocking_master_imp_decl,集合了blocking_put+get+peek_img的功能,master
- uvm_nonblocking_master_imp_decl,集合了nonblocking_put+get+peek_img的功能
- uvm_master_imp_decl,集合了uvm_blocking_master_imp_decl和uvm_nonblocking_master_imp_decl的功能
- uvm_blocking_slave_imp_decl,集合了blocking_put+get+peek_img的功能,slave,与master的区别,一是名字不一样,二是mask不一样,这个mask在UVM_MS_IMP_COMMON宏中赋给了m_if_mask(没错,slave这里也是用的UVM_MS_IMP_COMMON)
- uvm_nonblocking_slave_imp_decl,集合了nonblocking_put+get+peek_img的功能
- uvm_slave_imp_decl,集合了uvm_blocking_slave_imp_decl和uvm_nonblocking_slave_imp_decl的功能
- uvm_blocking_transport_imp_decl,实现了一中transport操作喽,transport相当于put+get,相关参数也是双份的,其他的就不讲了
- uvm_nonblocking_transport_imp_decl
- uvm_non_blocking_transport_imp_decl,调用uvm_nonblocking_transport_imp_decl
- uvm_transport_imp_decl,不介绍也懂是啥了吧
- uvm_analysis_imp_decl,如果有一个uvm_analysis_imp还好说,有多个的话也不用着急,可以用uvm_analysis_imp_decl来实现
- 除tlm接口声明系列宏外,还声明了UVM_SEQ_ITEM_PULL_IMP及各种mask的初始值。
can be used to load uvm into multiple scopes using a single compilation.)
? uvm_version_defines.svh ??uvm版本信息相关宏
? base
? uvm_globals.svh uvm_globals 介绍
? uvm_object_globals.svh uvm_object_globals 介绍
? uvm_object.svh uvm_object 介绍
? uvm_event.svh uvm_event 介绍
? uvm_event_callback.svh uvm_event_callback 介绍
? uvm_barrier.svh uvm_barrier 介绍
? uvm_coreservice.svh uvm_coreservice 介绍
? uvm_cmdline_processor.svh uvm_cmdline_processor 介绍
? uvm_resource.svh uvm_resource 介绍
? uvm_resource_db.svh uvm_resource_db 介绍
? uvm_resource_specializations.svh uvm_resource_specializations 介绍
? uvm_packer.svh uvm_packer 介绍
? uvm_queue.svh uvm_queue 介绍
? uvm_spell_chkr.svh uvm_spell_chkr 介绍
? uvm_pool.svh uvm_pool 介绍
? uvm_links.svh uvm_links 介绍
? uvm_comparer.svh uvm_comparer 介绍
? uvm_misc.svh uvm_misc 介绍
? uvm_heartbeat.svh uvm_heartbeat 介绍
? uvm_registry.svh uvm_registry 介绍
? uvm_recorder.svh uvm_recorder 介绍
? uvm_report_server .svh uvm_report_server 介绍
? comps ??所有直接扩展自uvm_component的class中,除了uvm_root/uvm_port_component_base在base目录、uvm_reg_predictor在reg目录、uvm_sequencer_base在seq目录、uvm_tlm_req_rsp_channel/uvm_tlm_fifo_base在tlm1目录、uvm_dhier_component在verdi目录及一些vmm相关的类外,其他agent/driver/monitor等大部分常见的都再这儿了。
? uvm_comps.svh ??头文件,在此处把本文件下的其他文件include进来,一共include了13个文件,也就是13个直接扩展至uvm_component的class。
? uvm_env.svh ??uvm_env,uvm environment,由uvm_component扩展而来,是个虚类,所有env都应扩展自uvm_env。uvm_env在uvm_component基础上没有过多扩展,做了两件事:
- 创建并初始化uvm_env
- 实现get_type_name函数返回type_name
uvm_agent做了4件事:
- 创建并初始化uvm_agent,new
- 实现get_type_name函数返回type_name
- 实现get_is_active函数,返回is_active的值。默认是UVM_ACTIVE的哈,但备不住用户会覆盖掉嘛。
- 实现build_phase。这里主要是到uvm_resource_pool中去读uvm_agent的is_active值。这里考虑得比较全面,考虑了用户自定义的is_active类型为string、uvm_bitstream_t、uvm_integral_t、unsigned、int等情况,对这些情况做类型转换。
uvm_driver中实现了3个port:
- seq_item_port是uvm_seq_item_pull_port类型的,有两个参数REQ和RSP,所有派生自uvm_driver的driver都应该用seq_item_port想sequencer请求items; seq_item_port也可以用来反馈响应给sequencer。
- seq_item_prod_if是uvm_seq_item_pull_port类型的,充当接口或桥,后边会把seq_item_port赋给seq_item_prod_if;
- rsp_port是uvm_analysis_port类型的,只有一个参数RSP,一般用rsp_port来反馈响应给sequencer,而不是上边提到的seq_item_port。driver采用哪种port连接sequencer取决于sequencer采用了哪种export,两者需要匹配。
uvm_driver做了2件事: - 创建并初始化uvm_driver,new函数值创建seq_item_port和rsp_port,seq_item_port指针给seq_item_prod_if。
- 实现get_type_name函数返回type_name
??uvm_push_driver做了5件事:
- 创建并初始化uvm_push_driver,new函数值创建req_export和rsp_port。
- 实现get_type_name函数返回type_name
- 实现check_port_connections函数检测port连接,如果req_export的size不为1的话报uvm_fatal
- put函数,调用push_driver中push,会报uvm_fatal
- end_of_elaboration_phase中自动调用check_port_connections检测port连接,把不符合规则的port连接扼杀在task phase之前
- 创建并初始化uvm_monitor
- 实现get_type_name函数返回type_name
- 创建并初始化uvm_test
- 实现get_type_name函数返回type_name
3. 创建并初始化uvm_scoreboard
4. 实现get_type_name函数返回type_name
? uvm_random_stimulus.svh ??uvm_random_stimulus直接派生自uvm_component,非虚类,参数化的类,参数类型为uvm_transaction。这个类最主要的功能就是,在达到最大计数次数或被叫停之前,随机生成transaction并通过blocking_put_port送出去。通过调用该类的stop_stimulus_generation即可停止仿真。new和get_type_name不说了,都有。
? uvm_in_order_comparator.svh ??含一个基类uvm_in_order_comparator及其两个派生类uvm_in_order_class_comparator、uvm_in_order_build_in_comparator。基类为通用component,非派生而来。
? uvm_algorithmic_comparator.svh ??跟uvm_in_order_comparator相比,这个uvm_algorithmic_comparator更上一层楼,支持比较两个不同类型的对象/类/其他类型。
? uvm_policies.svh ??uvm_policies.svh这文件中有很多class(通用component,非扩展自uvm_component),用以实现内建类型与基类类型不同时的多态操作:
?? 1. uvm_build_in_comp,比较两个内建类型并返回比较结果
?? 2. uvm_build_in_converter,传入指针返回字符串
?? 3. uvm_build_in_clone,顾名思义,clone输入值并作为返回值返回
?? 4. uvm_class_comp,比较两个内建类型并返回比较结果。a.compare(b),需要对象a自己提供compare方法。
?? 5. uvm_class_converter,传入指针返回字符串。t.convert2string(),需要对象t自己提供convert2string方法
?? 6. uvm_class_clone,顾名思义,clone输入对象并作为返回值返回。from.clone(),需要对象from自己提供clone方法。
?seq ? uvm_seq.svh ??头文件,把uvm sequence?相关的文件包含进来。此外还typedef了uvm_sequence类型的uvm_default_sequence_type,uvm_sequencer、uvm_driver、uvm_sequencer_param_base以此类推。
? uvm_sequence_item.svh ??uvm_sequenve_item直接从uvm_transaction派生而来,uvm_transaction从uvm_object派生而来。uvm_sequence_item这个类中内容如下所述。
- 成员变量,
- m_sequence_id,sequence id,local int类型,默认-1
- m_use_sequence_info,sequence占用标志位,protected bit类型
- m_depth,sequence depth信息,protected int类型,默认-1
- m_sequencer,发送该sequence的sequencer
- m_parent_sequence,parent sequence
- print_sequence_info,打印sequence信息标志位
- issued1,issued2
? uvm_sequence_base.svh ??uvm_sequence_base直接从uvm_sequence_item派生而来,该类内容如下所述。
- 方法(function/task)
- new,创建uvm_sequence_item
- get_type_name,返回字符串“uvm_sequence_item”
- get_full_name,不解释啦,会与get_name的值(leaf_name)拼接哦
- get_root_sequence,获取root sequence(没有parent sequence就是root
sequence啦)
- get_root_sequence_name,获取root sequence name
- get_sequence_path,获取sequence path,实现方法与get_root_sequence_name相似,区别在于get_sequence_path把搜索过程中的各个节点记录了下来,拼接成path
- set_sequence_id,设置m_sequence_id的值
- get_sequence_id,返回m_sequence_id的值
- set_id_info,设置item的id,输入参数类型是uvm_sequence_item,item为空报fatal,非空则:①获取item的id并赋值给m_transanction_id(见uvm_transaction.svh)
②获取item的sequence id并赋值给m_sequence_id
- set_depth,设置m_depth的值
- get_depth,返回m_depth值
- set_use_sequence_info,设置m_use_sequence_info的值
- get_use_sequence_info,返回m_use_sequence_info的值
- set_parent_sequence,设置m_parent_sequence,指定parenr sequence
- get_parent_sequence,获取m_parent_sequence
- m_set_p_sequencer,内部方法,返回空
- set_sequencer,设置m_sequencer,指定发送该sequence的sequencer
- get_sequencer,获取m_sequencer,获取发送该sequence的sequencer
- set_item_context,给当前sequence_item指定parent sequence及sequencer,depth值+1,重新分配seed
- is_item,item返回1,sequence返回0。代码里只有一行return(1),它会把uvm_sequence_base里is_item函数的return 0覆盖掉。
- uvm_report_info、uvm_ report_warning、uvm_ report_error、uvm_
report_fatal、do_print及其相关的uvm_get_report_object、uvm_report_enable、uvm_report。sequence或item打印信息时会用到sequencer,如果没有指明sequencer的话,则直接调用全局的reporter。(TODO。后边有时间再详细解释这个,我先往下看代码哇)
– 成员变量
-m_sequence_state,uvm_sequence_state有9个state详见uvm_object_globals.svh中的uvm_sequence_state枚举变量介绍
-m_next_transaction_id,默认为1
-m_priority,
-m_wait_for_grant_semaphore,
-m_sqr_seq_ids,
-children_array,
-response_queue,
-response_queue_depth,
-response_queue_error_report_disable
-do_not_randomize
-m_sequence_process,当前sequence进程
-m_use_response_handler,
-type_name,
-is_rel_default,
-wait_rel_default,
– 方法(function/task)
-new,创建并初始化uvm_sequence_base,m_sequence_state=UVM_CREATE,wait_for_grant_semaphore=0,m_init_phase_daps(1)
-is_item,item返回1,sequence返回0,默认返回0(因为当前为sequence)
-get_sequence_state,返回sequence state,return m_sequence_state
-wait_for_sequence_state,输入参数未state_mask,等待直到sequence
state符合state_mask为止
-get_tr_handle,获取transaction
handler,每一个recorder都有一个独一无二的id,为0表示该transaction已经被释放,详见uvm_recoreder.svh
-start,广为人知的seq.start(seq, sqr)就是在这儿实现的。该task按顺序做了以下事情:
-set_item_context
-判断sequence state是否在UVM_CREATE、UVM_STOPPED、UVM_FINISHED中,不在的话报uvm fatal
-如果parent sequence不为空的话,sequence.children_array置一
-如果sequence优先级小于-1,报fatal,这优先级溢出啦
-如果sequence优先级小于0(为-1),parentsequence为空优先级默认100,非空则使用parentsequence的优先级作为当前sequence的优先级
-清空当前sequence的response queue,确保已退出上次运行
-若sequencer非空,获取stream、handler、m_tr_recoder
-设置sequence id为-1,确保该sequence已终止执行
-若m_sequencer非空,注册sequence
-提起objection并锁住uvm_get_to_lock_dap,然后pre_start、pre_body、pre_do、mid_do、body、post_do、post_body、post_start一系列操作安排上,最后drop
objection
-清理现场,end_tr、m_sequence_exiting、children_array.dekete等
-body,用户需要自己写body来覆盖掉uvm_sequence_base里的body,不然会报uvm_warning
-set_starting_phase,不解释
-get_starting_phase,不解释
-set_automatic_phase_objection
-get_automatic_phase_objection
-m_safe_raise_staring_phase
-m_safe_drop_staring_phase
-set_priority,设置sequence优先级
-get_priority,获取sequence优先级
-is_relevant,默认is_relevant值为1,用户使用时需重载该函数,该函数用于sequencer仲裁,is_relevant为0时sequencer就不调用这个sequence
-wait_for_relevant,当所有sequence都不relevant时,等待relevant出现
-lock,锁住sequencer,具体在sequencer里再讲
-grab,抢占sequencer,直接插队到最先,比lock强势哦
-unlock,解锁
-ungrab,解除抢占
-is_blocked,返回sequencer block状态,如果lock或grab了,返回0,否则返回1
-has_lock,sequencer lock的话返回1,否则返回0
-kill,杀掉sequence,drop objection
-do_kill, m_kill,杀掉所有children sequence进程
-create_item, start_item, finish_item,见字如晤
-wait_for_grant,见字如晤,等待放行
-send_request,见字如晤,发送请求,一般在wait_for_gant之后用
-wait_for_item_done,等待item发送完毕
-use_response_handler,见字如晤
-get_use_response_handler,获取m_use_response_handler值
-response_handler,返回空
-set_response_queue_error_report_disable
-get_response_queue_error_report_disable
-set_response_queue_depth
-get_response_queue_depth
-clear_response_queue
-put_base_response
-put_response
-get_base_response
-constraint pick_sequence
-num_sequeces,返回sequence数目
-get_seq_kind,返回suquence类型
-get_sequence,获取指定类型的sequence
-do_sequence_kind,启动指定类型的sequence
-get_sequence_by_name,获取指定名字的sequence
-create_and_start_sequence_by_name,创建并启动指定名字的sequence
-m_get_sqr_sequence_id,获取指定sequencer的sequenceid,可指定get钱是否update
-m_set_sqr_sequence_id,设置指定sequencer的sequence id
? uvm_sequence.svh ??uvm_sequence直接从uvm_sequence_item扩展而来,是个参数化的类,两个参数分别为uvm_sequence_item类型的REQ和RSP。
– 成员变量
-uvm_sequence_item类型的REQ
-uvm_sequence_item类型的RSP
-uvm_sequencer_param_base类型的param_sequencer
– 方法(function/task)
-new,创建并初始化uvm_sequence
-send_request,给sequencer发送请求,请求sequencer发送item,可以设置rerandomize
bit 1,在发送之前随机一下item
-get_current_item,返回当前的item,如果m_sequencer到参数化的类param_seqyencer转换失败,会报fatal
-get_response,获取指定transaction的response
-put_response,给指定RSP设置response
-do_print,调用printer的print_object,打印REQ和RSP
? uvm_sequence_builtin.svh ??uvm_sequence_buildin中有两个类,①uvm_random_sequence,②uvm_exhaustice_sequence,③uvm_simple_sequence,为预定义的sequence,从uvm_sequence扩展而来。不详细解释啦。
? uvm_sequence_library.svh ??包含两个类,uvm_sequence_library及其cfg,均从uvm_sequence扩展而来。
??uvm_sequence_library里可以容纳很多sequence,可根据指定规则或随机创建/启动sequence。有时间再看。
? uvm_sequencer_base.svh ??uvm_sequencer_base直接派生自uvm_component。
-成员变量
-arb_sequence_q[$];
-arb_completed[int];
-lock_list[$];
-reg_sequences[int];
-m_sequencer_id;
-m_lock_arb_size;
-m_arb_size;
-m_wait_for_item_sequence_id,
-m_wait_for_item_transaction_id;
-m_wait_relevant_count = 0 ;
-m_max_zero_time_wait_relevant_count = 10;
-m_last_wait_relevant_time = 0 ;
-m_arbitration = UVM_SEQ_ARB_FIFO;
-g_request_id;
-g_sequence_id = 1;
-g_sequencer_id = 1;
-m_default_sequences[uvm_phase],sequence进程
– 方法(function/task)
-new,创建并初始化uvm_sequencer_base
-is_child,如果是child sequence,则返回1,否则返回0
-user_priority_arbitration,仅用于sequencer的UVM_SEQ_ARB_USER模式
-execute_item,运行指定的item
-start_phase_sequence,在当前phase下启动sequece
-stop_phase_sequence,在当前phase下停止sequence
-wait_for_grant,sequence等待放行
-wait_for_item_done,等待item传输完成
-is_blocked,返回block状态,block住了则返回1,否则返回0
-has_lock,如果当前sequencer有锁,返回1,否则返回0
-lock,sequence加锁
-unclock,解锁
-grab,sequence抢占
-ungrab,解除抢占
-stop_sequence,停止当前sequence
-is_grabed,如果当前sequencer被lock或grab,均返回1,否则返回0
-current_grabber,返回sequencer现在被谁lock/grab住了
-has_do_available,当前sequencer要发送的sequence,如果有ready的就返回1,否则返回0。
-set_arbitration,设置sequencer的仲裁模式,包括以下模式:
-UVM_SEQ_ARB_FIFO,默认模式,先入先出,FIFO
-UVM_SEQ_ARB_WEIGHTED,根据权重进行仲裁,相同权重随机选择
-UVM_SEQ_ARB_RANDOM,随机选择
-UVM_SEQ_ARB_STRICT_FIFO,最高优先级按照FIFO模式
-UVM_SEQ_ARB_STRICT_RANDOM,最高优先级按照随机模式
-UVM_SEQ_ARB_USER,用户自定义模式
-get_arbitration,获取当前仲裁模式
-wait_for_sequences,sequence等待item ready
-send_request,给sequencer发送请求,请求item
-其他内建的function/task,不列举了,敲得手疼
? uvm_sequencer_param_base.svh ??uvm_sequencer_param_base直接扩展自uvm_sequencer_base,参数化的类,参数是uvm_sequence_item类型的REQ
& RSP。跟uvm_sequencer_base相比,param_base主要新增了以下内容。
– 成员变量
-rsp_export,uvm_analysis_export类型
– 方法
-get_current_item,获取sequencer当前在执行的sequence item
-get_num_reqs_sent,返回sequencer发出的请求数量
-set_num_last_reqs,设置过往请求的保存数量上限,默认1,最大支持1024,超出会报警
-get_num_last_reqs,获取过往请求的保存数量上限
-last_req,返回上一次发出请求的item
-get_num_rsps_received,获取当前sequencer已接收的请求数目
-set_num_last_rsps,设置response保存数量上限,默认1,最大可设置为1024
-get_num_last_rsps,获取response保存数量上限
-last_rsp,返回上一次返回的response item
-connect_phase,把rsp_export与sqr_rsp_analysis_fifo.analysis_export相连
-build_phase,当前sequencer指针指向sqr_rsp_analysis_fifo.sequencer_ptr
-其他不建议直接使用的内建方法,不列举了
? uvm_sequencer.svh ??uvm_sequencer直接扩展自uvm_sequencer_param_base,而非uvm_sequencer_base,参数化的类,参数是uvm_sequence_item类型的REQ
& RSP。
??uvm_sequencer在uvm_sequencer_param_base的基础上,主要实现了以下方法,也是我们日常中接触比较多的几个方法:
-get_next_item,请求下一个item
-try_next_item
-item_done
-put
-get
-peek
-item_done_trigger
-item_done_get_trigger_data
? uvm_push_sequencer.svh ??uvm_push_sequencer直接扩展自uvm_sequencer_param_base,参数化的类,参数是uvm_sequence_item类型的REQ &RSP。它跟uvm_sequencer的区别在于,uvm_push_sequencer里实现了run_phase,在run_phase里先get再put,属于主动型的,不用在driver中get_next_item了。
? uvm_sequencer_analysis_fifo.svh ??uvm_sequencer_analysis_fifo从uvm_tlm_fifo继承而来,是个参数化的类,参数是uvm_sequence_item类型的RSP。该类中重点是重写了tlm_fifo的write函数,调用uvm_sequencer_base的analysis_write来写。
? direct ??Synopsys自家的东西,非UVM标准。两个文件,其一include uvm_seed.svh,其二uvm_seed.svh这个文件DPI-C调用C实现uvm单向哈希算法及创建随机seed。别无其他。
? uvm_direct.svh ? uvm_seed.vh
? dap ??dap全称是data access policy,即uvm的数据访问策略。除容器文件uvm_dap.svh之外,实现了四个类: ① uvm_set_get_dap_base;② uvm_simple_lock_dap; ③ uvm_get_to_lock_dap; ④ uvm_set_before_get_dap。从名称中容易看出,uvm_set_get_dap_base是基类,其直接从uvm_object扩展得到,是个参数化的类(参数type T=int),另外3个都是从这个基类中扩展出来的。
? uvm_dap.svh ??头文件或称容器文件,把另外四个文件include进来。
? uvm_set_get_dap_base.svh ??uvm_set_get_dap_base是个参数化的类,从uvm_object直接扩展而来。该类提供了UVM数据访问的四大接口:set、try_set、get和try_get。set/get是在resource(中文咋翻译?池子?)内进行set/get的数据访问操作,操作失败的话会报error;try_set/try_get的意思也很明显了,操作成功返回1,操作失败不会报错,但会返回0。
? uvm_simple_lock_dap.svh ??class uvm_simple_lock_dap从uvm_set_get_tap_base扩展而来,简单来说是给数据访问加了个锁(lock)。这个锁相对简单,通过1bit数据m_locked来控制能否set/get数据。m_locked默认为0,即unlocked,通过调用函数lock( )及unlock( )改变m_locked的值实现上锁及开锁。函数is_locked( )返回m_locked值。
??unlock状态下,对数据进行set会正常更新数据,locked状态下set则报出uvm_error;locked时,try_set正常更新数据并返回1,unlocked时则不能更新数据并返回0,但不会报uvm_error/warning等任何提示信息。
??相较于set,无论locked还是unlocked,get、try_get操作都会正确得到数据值,且try_get时钟返回1。
??由于copy/pack等操作存在违背lock策略的潜在风险,uvm_simple_locked_dap不支持do_copy、do_pack、do_unpack的操作,当调用这些函数时会报uvm_error。do_print不涉及数据读写的操作,所以do_print( )是支持的。
??还有一个函数,convert2string,这个函数用来打印数据及其locked/unlocked状态。
? uvm_set_before_get_dap.svh ??uvm_set_before_get_dap从uvm_set_get_tap_base扩展而来,在数据get操作之前确保该数据被set过至少一次。该类有一个重要的意义,在多个component间传递共享信息,即便这些信息还没准备好,相当于是在ready之前发生一个占位符。
??具体实现方法是,在set/try_set操作时把指示位m_set置1,get时判断m_set状态,为1则表示至少set/try_set过1次,否则表示没有set/try_set过。未set过,get操作会报uvm_error但仍然会返回正确的value,try_get则只有在set之后才更新数据值,并返回1,未set得不到数据值且返回0。
??不支持do_copy、do_pack、do_unpack,支持do_print,函数convert2string显示数据及SET/UNSET状态。
? uvm_get_to_lock_dap.svh ??uvm_get_to_lock_dap从uvm_set_get_tap_base扩展而来,该类的一大用途是保护starting_phase & auto_objection,具体用法后边再讲吧。
??该类中,get/try_get之前进行set操作是没有任何问题的,在get/try_get操作之后锁住数据,m_locked=1,此时再进行set操作会报uvm_error。get之后try_set不报错,set失败且返回0。
??不支持do_copy、do_pack、do_unpack,支持do_print,函数convert2string显示数据及LOCKED/UNLOCKED状态。
? include ??Synopsys家读写寄存器用个几个文件,尚未发表,不是UVM标准的一部分,snps_reg_units.h重定义了无符号数据类型uint8, uint16, uint32 & uint64,此外便是用纯C和uvmC实现寄存器读写的两个文件,分别放在了pureC和uvmC文件夹下,文件名均为snps_reg_rw_api.h
? snps_reg_uints.h ? pureC ? snps_reg_rw_api.h
??API,纯C实现寄存器读写
? uvmC ? snps_reg_rw_api.h
??API,uvmC实现寄存器读写。
? dpi ? uvm_dpi.cc ??头文件,include了, uvm_dpi.h, uvm_commen.c, uvm_regex.cc, uvm_hdl.cc, uvm_svcmd_dpi.cc,只有在定义了“__cplusplus”时才有效。编译器可以直接编译该文件,或单独编译该文件include的几个文件,方便用户使用。
? uvm_dpi.h ??include UVM中C/C++用到的头文件,包括,
? uvm_dpi.svh ??UVM DPI子程序顶层文件,include了uvm_hdl.svh, uvm_svcmd_dpi.svh,和uvm_regex.svh。如果工具自带DPI,可以加宏UVM_NO_DPI来关掉DPI。
? uvm_common.c ??UVM DPI通用方法的实现,包括m__uvm_report_dpi, m_uvm_report_dpi及int_str_max。
? uvm_hdl.c ??根据defined的宏,决定include哪家的uvm_hdl.c。对应关系如下:VCS/VCSMX -> uvm_hdl_vcs.c,QUESTA -> uvm_hdl_questa.c,INCA/NCSC -> uvm_hdl_inca.c,没有相关定义的话会报错。
? uvm_hdl.svh ??定义HDL后门访问的最大比特向量宽度,没有define UVM_HDL_MAX_WIDTH的话默认是1024bit,否则以自主定义的值为准。uvm后门访问几个方法在此处import进来(DPI-C),这几个方法就是我们常用的uvm_hdl_check_path, uvm_hdl_deposit, uvm_hdl_force, uvm_hdl_force_time, uvm_hdl_release_and_read, uvm_hdl_release, uvm_hdl_read, uvm_hdl_read_string, uvm_memory_load。如果define了UVM_HDL_NO_DPI,使用以上方法是会报uvm_fatal的。
??以上几个方法中,使用概率较小的是uvm_hdl_force_time,其有3个参数,一是hierarchy路径,二是data值,但是force要保持的时间。时间值默认为0,如果没有指定这个时间值,则采用uvm_hdl_deposit的方法赋值。
uvm_memory_load也很少用到,其有7个输入参数,具体使用方法见uvm_hdl_vcs.c。
? uvm_hdl_inca.c ??inca家uvm backdoor访问hdl的C code实现,不具体讲了,有兴趣可以自己看。
? uvm_hdl_questa.c ??questa家uvm backdoor访问hdl的C code实现,不具体讲了,有兴趣可以自己看。
? uvm_hdl_vcs.c ??vcs家uvm backdoor访问hdl的C code实现,不具体讲了,有兴趣可以自己看。这个讲得最详细。
? uvm_regex.svh ??import 3个字符串匹配的DPI-C,分别是uvm_re_match, uvm_dump_re_cache, uvm_glob_to_re。如果定义了UVM_REGEX_NO_DPI的话,采用了sv实现uvm_re_match,但另外两个没有具体实现,是个宏的function。
? uvm_regex.cc ??上文提到的3个DPI-C的C函数实现。
??uvm_re_match不比多说,uvm的字符串匹配,两个参数,其一是表达式,其二是带匹配的字符串,跟python的re.match()用法类似。
uvm_glob_ro_re,把全局表达式转换为标准的正则表达式?没看懂啥意思,但看code的意思,该函数主要是实现特殊字符的替换,比如*-> .*,+ -> .+,.-> \., ? -> ., [ -> \\[, ] -> \\], ( -> \\(, ) -> \\)。
??uvm_dump_re_cache是从cache中dump常规表达式集。
? uvm_svcmd_dpi.svh ??import了3个DPI-C,分别为uvm_dpi_get_next_arc_c, uvm_dpi_get_tool_name_c, uvm_dpi_get_tool_version_c,并实现了3个sv function(其实也是直接调用DPI),即以上DPI名称去掉“_c”后缀,用以区分sv和C。
??除上段提到的3个DPI-C外,还import了另外3个,uvm_dpi_reg_comp, uvm_dpi_regexec, uvm_dpi_regfree。具体实现在下文.c里讲。
??如果define了UVM_CMDLINE_NO_DPI,调用以上DPI时会返回空/NULL或“?”。
? uvm_svcmd_dpi.c ??uvm_dpi_get_next_arc_c, uvm_dpi_get_tool_name_c, uvm_dpi_get_tool_version_c, uvm_dpi_reg_comp, uvm_dpi_regexec, uvm_dpi_regfree的C code实现。
- uvm_dpi_get_next_arc_c,dpi从命令行读取下一个参数;
- uvm_dpi_get_tool_name_c,获取工具名称信息;
- uvm_dpi_get_tool_version_c,获取工具版本信息;
- uvm_dpi_reg_comp,编译正则表达式;
- uvm_dpi_regexec,执行正则表达式,开始匹配;
- uvm_dpi_regfree,释放正则表达式。
? readme.important ??解释了为什么不推荐使用。因为本文件夹下的内容是内部实现用,不是uvm标准,没有形成文档,未来的uvm版本中有可能删除这些内容,即便是有修改也可能没有相关notice。
? uvm_resource_converter.svh ??本文件内的以下class都不推荐使用:
- m_uvm_resource_converter
- m_uvm_resource_converters
- m_uvm_resource_default_convert
- m_uvm_resource_convert2string_converter
- m_uvm_resource_sprint_converter