最全UVM源码解读,UVM-1,C C++社招面试题

img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

+ [◽ uvm\_sequence.svh](#9725_uvm_sequencesvh_625)
+ [◽ uvm\_sequence\_builtin.svh](#9725_uvm_sequence_builtinsvh_645)
+ [◽ uvm\_sequence\_library.svh](#9725_uvm_sequence_librarysvh_649)
+ [◽ uvm\_sequencer\_base.svh](#9725_uvm_sequencer_basesvh_655)
+ [◽ uvm\_sequencer\_param\_base.svh](#9725_uvm_sequencer_param_basesvh_712)
+ [◽ uvm\_sequencer.svh](#9725_uvm_sequencersvh_737)
+ [◽ uvm\_push\_sequencer.svh](#9725_uvm_push_sequencersvh_753)
+ [◽ uvm\_sequencer\_analysis\_fifo.svh](#9725_uvm_sequencer_analysis_fifosvh_756)

前言

近期比较闲,终于可以系统性地看下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_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

◽ uvm_deprecated_defines.svh

以下宏不建议使用:

·m_uvm_register_sequence
·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_global_defines.svh

UVM全局宏,主要有3个,UVM_MAX_STREAMBITS(4096)、UVM_PACKER_MAX_BYTES(4096)及超时退出默认值UVM_DEFAULT_TIMEOUT(9200s)

◽ 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_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

◽ uvm_phase_defines.svh

文件描述写得很明白了,这个文件中的define是给uvm_root.svh用的,用以简单创建所有的phase。这些宏仅能够创建uvm内建的phase,因为其实从uvm_component来的,不支持自定义的phase。如果需要实现更复杂的phase,用户可以从uvm_task/topdown/bottomup_phase基类中派生出新的类,然后细化一下exec_task或exec_func就可以啦。

m_uvm_task_phase实现了一个直接扩展自uvm_task_phase的类,详情可查看base/uvm_task_phase.svh的解读。

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_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_tlm_defines.svh

tlm imp接口声明系列宏:

  • 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的初始值。

◽ uvm_undefineall.svh

本文件用以解除所有uvm库自己define的宏,这样单次编译就能load到多个scope中。(恕我资浅,没看懂啥意思,原文附上:This
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基础上没有过多扩展,做了两件事:

  1. 创建并初始化uvm_env
  2. 实现get_type_name函数返回type_name

◽ uvm_agent.svh

uvm_agent,直接扩展至uvm_component,是个虚类,所有用户自定义的agent都应扩展自uvm_agent。agent下通常有3个子component:sequencer、driver和monitor。uvm_agent下有个枚举变量is_active,默认值为UVM_ACTIVE。UVM_ACTIVE时,3个子component都会包含进来,一般用在dut输入端;UVM_PASSIVE时则只有uvm_monitor这一个,一般放在dut的输出端。
uvm_agent做了4件事:

  1. 创建并初始化uvm_agent,new
  2. 实现get_type_name函数返回type_name
  3. 实现get_is_active函数,返回is_active的值。默认是UVM_ACTIVE的哈,但备不住用户会覆盖掉嘛。
  4. 实现build_phase。这里主要是到uvm_resource_pool中去读uvm_agent的is_active值。这里考虑得比较全面,考虑了用户自定义的is_active类型为string、uvm_bitstream_t、uvm_integral_t、unsigned、int等情况,对这些情况做类型转换。

◽ uvm_driver.svh

uvm_driver直接扩展至uvm_component,是个参数化的类,有两个参数,为REQ=uvm_sequence_item及RSP=REQ。所有用户自定义的driver都应该扩展自uvm_driver。uvm_driver不是虚类,也就是说,子类中不可以重载其中发函数和任务。
uvm_driver中实现了3个port:

  1. seq_item_port是uvm_seq_item_pull_port类型的,有两个参数REQ和RSP,所有派生自uvm_driver的driver都应该用seq_item_port想sequencer请求items; seq_item_port也可以用来反馈响应给sequencer。
  2. seq_item_prod_if是uvm_seq_item_pull_port类型的,充当接口或桥,后边会把seq_item_port赋给seq_item_prod_if;
  3. rsp_port是uvm_analysis_port类型的,只有一个参数RSP,一般用rsp_port来反馈响应给sequencer,而不是上边提到的seq_item_port。driver采用哪种port连接sequencer取决于sequencer采用了哪种export,两者需要匹配。
    uvm_driver做了2件事:
  4. 创建并初始化uvm_driver,new函数值创建seq_item_port和rsp_port,seq_item_port指针给seq_item_prod_if。
  5. 实现get_type_name函数返回type_name

◽ uvm_push_driver.svh

uvm_push_driver,看脸也是uvm_driver的近亲。跟uvm_driver不同的是,uvm_driver主动接收transaction,而uvm_push_driver是被动接收transaction,从push这个词也能猜到嘛,积极主动就不用push了。uvm_push_driver的“被动”体现在它不主动请求transaction,要等sequencer给它发。还记得uvm_driver里有个seq_item_port不?uvm_push_driver没有这个,取而代之的是uvm_blocking_put_imp类型的req_export,看到没,是export。uvm_push_driver也需要uvm_push_sequencer跟它配对连接,不是一家人不进一家门,此处按下不提了。
  uvm_push_driver做了5件事:

  1. 创建并初始化uvm_push_driver,new函数值创建req_export和rsp_port。
  2. 实现get_type_name函数返回type_name
  3. 实现check_port_connections函数检测port连接,如果req_export的size不为1的话报uvm_fatal
  4. put函数,调用push_driver中push,会报uvm_fatal
  5. end_of_elaboration_phase中自动调用check_port_connections检测port连接,把不符合规则的port连接扼杀在task phase之前

◽ uvm_monitor.svh

uvm_monitor,由uvm_component扩展而来,是个虚类,所有用户自定义的monitor都应扩展自uvm_monitor。uvm_monitor在uvm_component基础上没有过多扩展,做了两件事:

  1. 创建并初始化uvm_monitor
  2. 实现get_type_name函数返回type_name

◽ uvm_test.svh

uvm_test,由uvm_component扩展而来,是个虚类,所有testcase都应直接或间接扩展自uvm_test,只有这样,才能实现在命令行指定UVM_TESTNAME执行uvm_root::run_test。uvm_test在uvm_component基础上没有过多扩展,做了两件事:

  1. 创建并初始化uvm_test
  2. 实现get_type_name函数返回type_name

◽ uvm_scoreboard.svh

uvm_scoreboard直接扩展自uvm_component,虚类,所有用户自定义的scoreboard都应直接或间接扩展自uvm_scoreboard。scoreboard计分板在uvm_component基础上没有过多扩展,做了两件事:
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
  • 方法(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。后边有时间再详细解释这个,我先往下看代码哇)

◽ uvm_sequence_base.svh

uvm_sequence_base直接从uvm_sequence_item派生而来,该类内容如下所述。

– 成员变量

-   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),parent  sequence为空优先级默认100,非空则使用parent  sequence的优先级作为当前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等


![img](https://img-blog.csdnimg.cn/img_convert/daf9e49ed82969b784ce1aee323eca92.png)
![img](https://img-blog.csdnimg.cn/img_convert/33ebab94fe436aeb0b73fc33720417e7.png)

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618668825)**

sequence state是否在UVM_CREATE、UVM_STOPPED、UVM_FINISHED中,不在的话报uvm fatal
    -   如果parent sequence不为空的话,sequence.children_array置一
    -   如果sequence优先级小于-1,报fatal,这优先级溢出啦
    -   如果sequence优先级小于0(为-1),parent  sequence为空优先级默认100,非空则使用parent  sequence的优先级作为当前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等


[外链图片转存中...(img-1NdO6zhf-1715819228319)]
[外链图片转存中...(img-Mf2NmpvV-1715819228320)]

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618668825)**

  • 16
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值