第三章. UVM基础
3.1 uvm_component与uvm_object
component和object是UVM中两大基本的概念。
uvm_object是UVM中最基本的类,几乎所有的类都继承自uvm_object,包括uvm_component。
uvm_component有大量特性是uvm_object所没有的,一是通过在new时候制定parent参数来形成一种树形的组织结构,二是有phase的自动执行特性(uvm_component与uvm_object的不同之处)。
只有基于uvm_component派生的类才可能成为UVM书的结点。
3.1.1 常用的派生自uvm_object的类
uvm_sequence_item:transaction要从uvm_sequence_item派生。transaction就是封装了一定信息的类。
uvm_sequence:所有的sequence要从uvm_sequence派生,sequence就是sequence_item的组合。
config:所有的config直接从uvm_object派生,config的主要功能是规范验证平台的行为方式。
uvm_reg_item:派生自uvm_sequence_item,用于register model中。
uvm_phase:派生自uvm_object,控制uvm_component的行为方式,使得uvm_component平滑地在各个不同的phase之间依次运转。
uvm_reg_map,uvm_mem,uvm_reg_field,uvm_reg,uvm_reg_field,uvm_reg_block等与寄存器相关的众多的类都是派生自uvm_object,都是用于register model。
3.1.2 常用的派生自uvm_component的类
uvm_driver:所有的driver都要派生自uvm_driver,driver的功能主要就是向sequencer索要sequence_item,并将sequence_item的信息驱动到DUT的端口上,这相当于完成了从transaction级别到DUT能够接受的端口级别信息的转换。与uvm_component相比,uvm_driver多了一下几个成员变量:
uvm_seq_item_pull_port #(REQ, RSP) seq_item_port;
uvm_seq_item_pull_port #(REQ, RSP) seq_item_prod_if
REQ req;
RSP rsp;
函数和任务上,uvm_driver并没有做过多的扩展。
uvm_monitor:所有的monitor都要派生自uvm_monitor。monitor做的事情刚好跟driver相反,monitor从DUT的端口上接收数据,并且把接收到的数据转换成transaction级别的sequence_item,再把转换后的数据发送个scb。与uvm_component相比,uvm_monitor几乎没有做任何扩充。虽然理论上来说所有的monitor都要从uvm_monitor派生,但实际上从uvm_component派生,也是没有任何问题。
uvm_sequencer:所有的sequencer都要派生自uvm_sequencer。sequencer的功能就是组织管理sequencer。当driver要求数据时,他就把sequence生产的sequence_item转发给driver。与uvm_component相比,uvm_sequencer做了相当多的扩展。
uvm_scoreboard:一般的scoreboard都要派生自uvm_scoreboard。scoreboard的功能就是比较reference model分别发送来的数据,根据比较结果判断DUT是否正确工作。uvm_scoreboard也几乎没有在uvm_component的基础上做拓展。
reference model:UVM中并没有针对refm定义一个类。通常来说,refm都是直接派生自uvm_component。refm作用就是模仿DUT,完成与DUT相同的功能。DUT是用V写成的时序电路,refm可以用SV高级的特性。同时还可以通过DPI等接口调用其他语言来完成DUT相同的功能。
uvm_agent:所有的agent要派生自uvm_agent。uvm_agent的作用并不是那么明显,只是把driver和monitor封装在一起,根据参数值来决定是只实例化monitor还是要同时实例化driver和monitor。agent的使用主要是从可重用性的角度来考虑。如果在做验证平台时不考虑可重用性,那么agent其实可有可无。与uvm_component相比,uvm_agent的最大改动是引入了一个变量is_active。
uvm_active_passive_enum is_active = UVM_ACTIVE;
uvm_env:所有的env都要派生自uvm_env。env将验证平台上用到的固定不变的component都封装在一起。这样,当要运行不同的测试用例时,只要在测试用例中实例化此env即可。uvm_env并没有在uvm_component的基础上做过多扩展。
uvm_test:所有的测试用例要派生自uvm_test或其派生类,不同的测试用例之间差异很大,所以从uvm_test派生出来的类各不相同。任何一个派生出的测试用例中,都要实例化env,只有这样,当测试用例在运行的时候,才能把数据正常地发送给DUT,并正常地接收DUT的数据。uvm_test几乎没有在uvm_component的基础上做拓展。
3.1.3 与uvm_object相关的宏
uvm_object_utils:把一个直接或间接派生自uvm_object的类注册到factory中。
uvm_object_param_utils:把一个直接或间接派生自uvm_object的参数化的类注册到factory中。
uvm_object_utils_begin:当需要使用field_automation机制时,需要使用此宏。
uvm_object_param_utils_begin:适用于参数化的类且其中某些成员变量需要使用field_automation机制实现的类。
uvm_object_utils_end:总是和uvm_obeject_*_begin成对出现,作为factory注册的结束标志。
3.1.4 与uvm_component相关的宏
uvm_component_utils:用于把一个直接或间接派生自uvm_component的类注册到factory中。
uvm_component_param_utils:把一个直接或间接派生自uvm_component的参数化的类注册到factory中。
uvm_component_utils_begin:与uvm_object_utils_begin相似,用于同时需要使用factory机制和field_automation机制注册的类。
uvm_component_param_utils_begin:与uvm_component_utils_begin宏一样,只是它适用于参数化的,其中某些成员变量需要用field_automation机制实现的类。
uvm_component_utils_end:总是与uvm_component_*_begin成对出现,作为factory注册的结束标志。
3.1.5 uvm_component的限制
- uvm_object中的clone函数,uvm_component无法使用;
- 实例化uvm_component时,位于同一个父结点下的不同的component,在实例化时不能使用相同的名字。
3.2 UVM的树形结构
3.2.1 uvm_component中的parent参数
UVM通过uvm_component来实现树形结构。所有的UVM树的结点本质上都是一个uvm_component。b的根节点为a(b实例化时,parent=a),那么a内部会维护一个数组m_children,当b实例化时,就把b实例的指针加入到a的m_children数组中。这样a就知道b是自己的孩子,同时也才能让b知道a是自己的父母。当b有了自己的孩子时,即b的m_children中加入孩子的指针。
3.2.2 UVM树的根
UVM中真正的树根是一个称为uvm_top的东西。uvm_top是一个全局变量,他是uvm_root的一个实例。而uvm_root派生自uvm_component,所以uvm_top本质上是一个uvm_component,他是树的根。uvm_test_top的parent是uvm_top,uvm_top的parent是null。
如果一个component在实例化时,其parent被设置为null,那么这个component的parent将会被系统设置为系统中唯一的uvm_root的实例uvm_top。uvm_root的存在可以保证整个验证平台中只有一棵树(singleton单例模式),所有结点都是uvm_top的子结点。
在验证平台中,如需要得到uvm_top,由于uvm_top是一个全局变量,可以直接使用uvm_top。除此之外,还可以使用以下方法得到uvm_root。
uvm_root top;
top = uvm_root::get();
3.2.3 层次结构相关函数
UVM中提供了一系列的接口函数用于访问UVM树中的结点。
get_parent:用于得到当前实例的parent,一个component只有一个parent,所以get_parent不需要指定参数。
get_child:需要一个string类型的参数name,表示次child实例在实例化时指定的名字。
get_children:得到一个component的所有函数。参数类型为ref uvm_component children[$]。
get_first_child:得到第一个孩子。
get_next_child:得到下一个孩子,配合get_first_child函数,用于对get_children得到的孩子队列遍历。
get_num_children:返回当前component所拥有的child的数量。
3.3 field automation机制
3.3.1 几种常见的与field_automation相关的宏
与变量有关的uvm_field宏:
`uvm_field_int(ARG, FLAG) //整数
`uvm_field_real(ARG, FLAG) //实数
`uvm_field_enum(T, ARG, FLAG) //枚举
`uvm_field_object(ARG, FLAG) //object
`uvm_field_event(ARG, FLAG) //事件
`uvm_field_string(ARG, FLAG) //字符串
与动态数组有关的uvm_field宏:
`uvm_field_array_enum(ARG, FLAG) //枚举数组
`uvm_field_array_int(ARG, FLAG) //整型数组
`uvm_field_array_object(ARG, FLAG) //object数组
`uvm_field_array_string(ARG, FLAG) //字符串数组
与静态数组相关的uvm_field宏有:
`uvm_field_sarray_int(ARG, FLAG)
`uvm_field_sarray_enum(ARG, FLAG)
`uvm_field_sarray_object(ARG, FLAG)
`uvm_field_sarray_string(ARG, FLAG)
与队列相关的uvm_field宏有:
`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宏,出现的第一个类型是存储数据类型,第二个类型是索引类型,下面一共列举15种。如uvm_field_aa_int_string用于声明存储的数据是int,索引为string的类型的联合数组。
`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_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_short(ARG, FLAG)
`uvm_field_aa_int_short_unsigned(ARG, FLAG)
`uvm_field_aa_int_longint(ARG, FLAG)
`uvm_field_aa_int_longint_unsigned(ARG, FLAG)
`uvm_field_aa_string_int(ARG, FLAG)
`uvm_field_aa_object_int(ARG, FLAG)
3.3.2 field automation机制常用的函数
-
copy:用于实例的复制。
-
compare:比较两个实例是否一样。
-
pack_bytes:将所有的字段打包成byte流。
-
unpack_bytes:将一个byte流逐一恢复到某个类真的实例中。
-
pack:将所有字段打包成bit流。
-
unpack:将一个bit流逐一恢复到某个类的实例中。
-
pack_ints:将所有的字段打包成int流。
-
unpack_ints:将一个int流逐一恢复到某个类的实例中。
-
print:打印所有的字段。
-
clone:复制字段。
3.3.3 field automotion标志位
UVM的标志位本身是一个17bit的数字。parameter UVM_ALL_ON = `b0000_0010_1010_101。在UVM的标志位中:
-
bit0/1:copy/no_copy
-
bit2/3:compare/no_compare
-
bit4/5:print/no_print
-
bit6/7:record/no_record
-
bit8/9:pack/no_pack
-
其余7bit用作其他用途。
除了UVM_ALL_ON之外,还有UVM_NOCOMPARE,UVM_NOPRINT,UVM_NORECORD,UVM_NOCOPY等选项。
3.3.4 field automation中宏与if的结合
field automation可以结合if使用。当is_vlan为1时,注册vlan_info1~4字段。
if(is_vlan)begin
`uvm_field_int(vlan_info1, UVM_ALL_ON)
`uvm_field_int(vlan_info2, UVM_ALL_ON)
`uvm_field_int(vlan_info3, UVM_ALL_ON)
`uvm_field_int(vlan_info4, UVM_ALL_ON)
end
3.4 UVM中打印信息的控制
3.4.1 设置打印信息的冗余度阈值
UVM通过冗余度级别的设置提高了仿真日志的可读性。在打印信息之前,UVM会比较要显示信息的冗余度级别与默认的冗余度阈值,如果小于等于阈值,就会显示。否则不会显示。默认的冗余度阈值是UVM_MEDIUM。
通过get_report_verbosity_level函数得到某个component的冗余度阈值。此函数返回的是一个整数,整数含义如下:
-
UVM_NONE=0
-
UVM_LOW=100
-
UVM_MEDIUM=200
-
UVM_HIGH=300
-
UVM_FULL=400
-
UVM_DEBUG=500
UVM提供set_report_verbosity_level函数来设置某个特定component的默认冗余度阈值。由于涉及到层次引用,所以需要在connect_phase及之后的phase才能调用这个函数。如果不牵扯到任何层次引用,如设置当前component的冗余度阈值,则可以在connect_phase之前调用。set_report_verbosity_level只对某个特定的component起作用。而递归设置函数set_report_verbosity_level_hier则把当前component及其下所有子component的冗余度进行设置。
set_report_verbosity_level会对某个component内所有的uvm_info宏显示的信息产生影响。如果这些宏在调用时使用了不同的ID,那么可以使用set_report_id_verbosity函数来区分不同的ID的冗余度阈值。
env.i_agt.drv.set_report_id_verbosity("ID1", UVM_HIGH);
env.i_agt.set_report_id_verbosity("ID1", UVM_HIGH);
除了在代码中设置外,UVM支持在命令中设置冗余度阈值。
//两者作用相同
<sim command> +UVM_VERBOSITY=UVM_HIGH
<sim command> +UVM_VERBOSITY=HIGH
上述命令行参数将整个验证平台的冗余度阈值设置为UVM_HIGH。几乎相当于在base_test中调用set_report_verbosity_level_hier函数,把base_test及下所有的component的冗余度级别设置为UVM_HIGH。
set_report_verbosity_level_hier(UVM_HIGH)
在芯片级别的验证,重用了不同模块的env,通过设置不同env的冗余度级别,可以更好的控制整个芯片验证环境输出信息的质量。
3.4.2 重载打印信息的严重性
UVM默认有四种信息严重性
- UVM_INFO
- UVM_WARNING
- UVM_ERROR
- UVM_FATAL
这四种信息严重性可以互相重载。使用set_report_severity_override(UVM_XXX,UVM_XXXXX),前者为被重载的名称,后者为重载的名称。也可以指定重载某个component组件的信息严重性,使用set_report_severity_id_override(UVM_XXX,”component_name”, UVM_XXXXXX)来实现。
UVM不提供递归的严重性重载函数。严重性重载用的较少,一般只会对某个component内使用,不会递归使用。
重载严重性也可以在命令行中实现,调用方式为:
<sim command> +uvm_set_serverity=<comp>, <id>, <current serverity>, <new serverity>
3.4.3 UVM_ERROR到达一定数量结束仿真
当uvm_fatal出现时,表示出现了致命错误,仿真会马上停止。
UVM支持UVM_ERROR达到一定数量时结束仿真。对于某个测试用例,如果出现了大量的UVM_ERROR,根据这些错误已经可以确定bug所在了,再仿真下去意义已经不大,此时就可以结束仿真,而不必等到所有的objection被撤销。实现这个功能的是set_report_max_quit_count函数。可以在base_test中和测试用例中设置此函数,如果同时设置了此函数,则以测试用例中设置为准(顶层覆盖底层)。可以在build_phase以及其他phase设置此函数。
function void base_test::build_phase(uvm_phase phase);
super.build_phase(phase);
env = my_env::type_id::create("env", this);
set_report_max_quit_count(5);
endfunction
上述代码把退出的阈值设置为5,当出现5个UVM_ERROR时,会自动退出。
还可以在命令行中设置退出的阈值:
<sim command> +UVM_MAX_QUIT_COUNT=6, NO
get_max_quit_count:查询当前的退出阈值,如果返回值为0则表示无论出现多少个UVM_ERROR都不会退出仿真。
3.4.4 设置计数目标
上节中设置仿真停止的阈值中只包含UVM_ERROR,在计数当中是不包含UVM_WARNING的。可以通过设置set_report_serverity_action函数来把UVM_WARNING加入计数目标。
virtual function void connect_phase(uvm_phase phase);
set_report_max_quit_count(5);
env.i_agt.drv.set_report_severity_action(UVM_WARNING, UVM_DISPLAY|UVM_COUNT);
endfunction
set_report_severity_action:把其他严重性等级的信息加入计数目标。
set_report_severity_action_hier:将目标component及其下所有结点的信息加入到计数目标。
默认情况下,UVM_ERROR已经加入了统计计数。如果要其从统计计数目标中移除(除掉UVM_COUNT),可以使用以下语句:
env.i_agt.drv.set_report_severity_action(UVM_ERROR, UVM_DISPLAY);
还可以针对某个特定的ID进行计数:
set_report_id_action:把目标component所有信息加入到计数中。
set_report_id_action:递归将目标component及其所有子component加入到计数中。
env.i_agt.drv.set_report_id_action("my_drv", UVM_DISPLAY| UVM_COUNT);
UVM支持对严重性和ID进行联合起来设置。
env.i_agt.drv.set_report_severity_id_action(UVM_WARNING, "my_driver", UVM_DISPLAY| UVM_COUNT);
严重性和ID联合设置同样支持递归使用
env.i_agt.set_report_severity_id_action_hier(UVM_WARNING, "my_driver", UVM_DISPLAY| UVM_COUNT);
UVM支持在命令行中设置计数目标:
<sim command> +uvm_set_action=<comp>, <id>, <severity>, <action>
3.4.5 UVM的断点功能
在程序调试时,断点功能是非常有用的一个功能。在程序运行时,预先在某处设置一断点。当程序执行到此处时,停止仿真,进入交互模式,从而进行调试。
virtual function void connect_phase(uvm_phase phase);
env.i_agt.drv.set_report_severity_action(UVM_WARNING, UVM_DISPLAY| UVM_STOP);
endfunction
使用上述设置语句,当env.i_agt.drv中出现UVM_WARNING时,立刻停止仿真,进入交互模式。只要将UVM_COUNT替换成UVM_STOP,就可以实现相应的断点功能。同样也可以在命令行中设置UVM断点:
<sim command> +uvm_set_action="uvm_test_top.env.i_agt.drv", my_driver, UVM_WARNING, UVM_DISPLAY|UVM_STOP
3.4.6 将输出信息导入文件中
默认情况下,UVM会将UVM_INFO等信息显示在标准输出(终端屏幕)上。各个仿真器提供将显示在标准输出的信息同时输出到一个日志文件中的功能。UVM提供将特定信息输出到特定日志文件的功能。
UVM_FILE info_log;
UVM_FILE warning_log;
UVM_FILE error_log;
UVM_FILE fatal_log;
virtual function void connect_phase(uvm_phase phase);
info_log = $fopen("info.log", "w");
warning_log = $fopen("warning.log", "w");
error_log = $fopen("error.log", "w");
fatal_log = $fopen("fatal.log", "w");
env.i_agt.drv.set_report_severity_file(UVM_INFO, info_log);
env.i_agt.drv.set_report_severity_file(UVM_WARNING, warning_log);
env.i_agt.drv.set_report_severity_file(UVM_ERROR, error_log);
env.i_agt.drv.set_report_severity_file(UVM_FATAL, fatal_log);
env.i_agt.drv.set_report_severity_action(UVM_INFO, UVM_DISPLAY| UVM_LOG);
env.i_agt.drv.set_report_severity_action(UVM_WARNING, UVM_DISPLAY|UVM_LOG);
env.i_agt.drv.set_report_severity_action(UVM_ERROR, UVM_DISPLAY| UVM_COUNT | UVM_LOG);
env.i_agt.drv.set_report_severity_action(UVM_FATAL, UVM_DISPLAY|UVM_EXIT | UVM_LOG);
endfunction
上述代码将env.i_agt.drv的UVM_INFO输出到info.log,UVM_WARNING输出到warning log,UVM_ERROR输出到error.log,UVM_FATAL输出到fatal.log。
set_report_severity_file:根据信息的严重级别将指定的信息输入到指定的日志文件中。
set_report_severity_file_hier:递归形式指定component中的信息至指定的日志文件中。
set_report_id_file:根据信息的ID将指定的信息输入到指定的日志文件中。
set_report_id_file_hier:递归形式。
UVM还可以根据严重性和ID的组合设置不同的日志文件:
env.i_agt.drv.set_report_severity_id_file(UVM_INFO, "my_drv", drv_log);
3.4.7 控制打印信息的行为
UVM把UVM_DISPLAY定义为一个整数,不同的行为有不同的位偏移,可以使用或的方式将不同的行为组合在一起。UVM共定义如下几种行为:
UVM_NO_ACTION=’b0000_00; //不做操作
UVM_DISPLAY=’b0000_01; //输出到标准输出上(屏幕)
UVM_LOG=’b0000_10; //输出到日志
UVM_COUNT=’b0001_00; //作为计数目标
UVM_EXIT=’b0010_00; //退出仿真
UVM_CALL_HOOK=’b0100_00; //调用回调函数
UVM_STOP=’b1000_00; //停止仿真,进入命令行交互模式(UVM断点)
默认情况下,UVM设置了如下行为:
set_severity_action(UVM_INFO, UVM_DISPLAY);
set_severity_action(UVM_WARNING, UVM_DISPLAY);
set_severity_action(UVM_ERROR, UVM_DISPLAY | UVM_COUNT);
set_severity_action(UVM_FATAL, UVM_DISPLAY | UVM_EXIT);
可以通过设置UVM_NO_ACTION来关闭UVM信息的输出。
3.5 config_db机制
3.5.1 UVM中的路径
一个component内通过get_full_name()函数可以得到此component的路径。
uvm_test_top实例化的名字是uvm_test_top,这是由UVM在run_test时自动指定的。uvm_top的名字_top_,但是在显示路径的时候,并不会显示出这个名字,而只显示从uvm_test_top开始的路径。
路径是实例化各组件时指定的名称组成的(如下代码中的driver)。
层次结构是变量名称组成的(如下代码中的drv)。
drv = my_driver::type_id::create("driver");
良好的编码习惯中,这种变量名与其实例化时传递的名字不一致的情况应该尽量避免。
3.5.2 set与get函数的参数
config_db机制用于UVM验证平台间传递参数,他们通常是成对出现的。set函数寄信,get函数收信。
uvm_config_db #(int)::set(this, "env.i_agt.drv", "pre_num" ,100);
第一个参数必须是一个uvm_component实例的指针,第二个参数是相对于此实例的路径。第一个参数和第二个参数联合组成了目标路径,与此路径符合的目标才能收信。两个参数组合的形式组成路径增加了灵活性。
第三个参数表示一个记号,说明这个值是传给目标中那个成员的,第四个参数是要设置的值。
uvm_config_db #(int)::get(this, "", "pre_num", pre_num);
get函数中的第一个参数和第二个参数联合起来组成路径。第一个参数必须是一个uvm_component实例的指针,第二个参数是相对此实例的路径。第三个参数就是set函数中的第三个参数,这两个参数必须严格匹配,第四个参数则是要设置的变量。
config_db机制的set函数设置virtual interface时,set函数的第一个参数为null,这种情况下,UVM会自动把第一个参数替换为uvm_root::get(),即uvm_top。
set及get函数中的第三个参数可以与get函数中第四个参数不一样。如第四个参数是pre_num,那么第三个参数可以是p_num(set和get函数的前两个参数指明路径,路径相同才可以接收。第三个参数set和get保持一致,是约定好的标记,可以通过这个标记将set的第四个参数传递给get的第四个参数的变量),只要保持set和get中的第三个参数一致即可:
uvm_config_db #(int)::set(this, "env.i_agt.drv", "p_num", 100);
uvm_config_db #(int)::get(this, "", "p_num", pre_num);
3.5.3 省略get语句
set与get函数一般都是成对出现的,但是某些情况下,是可以只有set而没有get语句的,即省略get语句。
只要使用uvm_field_int注册字段,并且在build_phase中调用super.build_phase(),就可以省略在build_phase中的get语句。这里关键是build_phase中的super.build_phase语句,当执行到super.build_phase时,会自动执行get语句。这种做法的前提是:
- my_driver必须使用uvm_component_utils宏注册
- 传递的数据(使用get函数获取参数的变量名)必须使用uvm_field_int宏注册
- 在调用set函数时,set函数的第三个参数必须要与get函数变量的名字一致。
3.5.4 跨层次的多重设置
不同层次的component对同一变量多次设置,层次高的component设置有效。这个层次指的是UVM树中的位置,越靠近根结点uvm_top,则认为其层次越高;
在使用config_db设置参数时,uvm_root具有最高的优先级。因此在调用config_db::set函数时,第一个参数尽量使用this。在无法的到this指针时,使用null或者uvm_root::get()。
3.5.5 同一层次的多重设置
同一层次对同一变量进行设置,则后一次设置的值生效。
3.5.6 非线性的设置和获取
UVM树中的组件设置/获取另一个处于同一层次结构的组件称为非线性设置/获取。由于UVM并没有定义同一层次的执行顺序,非直线获取会具有一定的风险性。
3.5.7 config_db机制对通配符的支持
config_db支持通配符,简化代码,用起来很方便,但是不推荐使用通配符。通配符的存在使得设置路径不易理解,所以尽量避免使用通配符。如果要使用,尽可能不要过于省略。
3.5.8 check_config_uasge
显示出截止到此函数调用时哪些参数是被设置过但是却没有被获取过。由于config_db的set和get语句一般用于build_phase阶段,所以此函数一般在connect_phase被调用。也可以在connect_phase后的任一phase被调用。
3.5.9 set_config与get_config
set_config与get_config来自于OVM(旧版本中的代码),UVM继承了这种写法(可以使用UVM中config_db来代替),并在此基础上发展出了config_db。set_config与get_config已经过时。set_config_int与uvm_config_db#(int)::set是完全等价的;get_config_int与uvm_config_db#(int)::get是完全等价的。config_db比set/get_config强大的地方在于,他设置的参数类型并不局限于int/object/string。
3.5.10 config_db的调试
print_config(X):参数1表示递归查询,0表示只显示当前component的信息。他会遍历整个验证平台的所有结点,找出哪些被设置过的信息对他们是可见的。
UVM还提供一个命令行参数UVM_CONFIG_DB_TRACE来对config_db进行调试:
<sim command> +UVM_CONFIG_DB_TRACE
参考文献:
UVM实战(卷Ⅰ)张强 编著 机械工业出版社