UVM入门进阶2

发布时间 2023-07-15 21:41:17作者: Fireworks、

UVM入门和进阶2

核心基类(uvm_object)

在UVM世界的类库地图中除过事务接口类继承于uvm_port_base,其他所有的类都是从uvm_object类一步步继承来的
域的自动化:UVM通过域的自动化,使得用户在注册UVM类的同时也可以声明今后会参与到对象复制、克隆、打印等操作的成员变量,可以以简化对象的复制
Alt text
在注册component或object时,使用'uvm_{component,object}utils_begin和'uvmutils_end来配对包裹接下来的域的自动化
域的自动化的相关宏都是uvm_field
(ARG,FLAG)ARG表示成员变量,FLAG表示用来标记的数据操作,FLAG的具体表示初学者默认使用UVM_ALL_ON或者UVM_DEFAULT
域的自动化宏可以看出,在注册的同时声明了将来参与uvm_object数据操作的成员变量。凡是声明了的成员变量,都将在数据操作时自动参与进来,即会自动参与到数据的比较,复制和打印等

copy,clone

copy:默认已经创建好了对象,只需要对数据进行拷贝;clone:自动创建对象并对源对象进行数据拷贝,再返回目标对象的句柄
定义回调函数格式function void do_copy(uvm_object_rhs);

compare

定义回调函数格式function bit compare(uvm_object rhs,uvm_comparer compare=null);

print

定义回调函数格式function void do_print(uvm_printer printer = null);

pack/unpack

定义回调函数function bit pack/unpack(ref bit bit_stream,input uvm_packer packer = null);

phase机制

phase机制可以帮助我们将UVM仿真阶段清晰地进行层次化
UVM的9个主要的phase列表。执行顺序:自上而下
Alt text
只有run_phase是一个可以耗时的任务。其他的phase对应的方法都是函数,必须立即返回
build_phase和final_phase是自顶向下,其他的都是自底向上

run_phase中的12个分支phase
run_phase和12个分支phase是并行执行的

UVM编译和运行顺序

在加载硬件模型调用仿真器之前,需要完成编译和建模阶段
在开始仿真之前,会分别执行硬件的always/initial语句,以及UVM的调用测试方法run_test和几个phase,分别是build,connect,end_of_elaboration和start_of_simulation

在开始仿真后,将会执行run_phase或者对应的12个细分的phase
在仿真结束后,将会执行剩余的phase,分别是extract,check,report和final

仿真结束

结束仿真的机制有且只有一种,那就是利用objection挂起机制来控制仿真结束。建议在一进入run_phase()后就挂起。

仿真过程里面,在run_phase的阶段,至少要有一个组件挂起objection,即举手防止仿真退出。在仿真结束后,要使用drop_objection落下objection,退出run_phase。如果在run_phase时,环境里面没有任何组件举手,那么会立即退出run_phase,进入到下一阶段

config机制

使用形式:
uvm_config_db#(T)::set(uvm_component cntxt,string inst_name,string field_name,T value);
第一个和第二个参数联合起来形成目标路径。第一个参数是uvm_component实例的指针,第二个参数是相对此实例的路径,第三个参数表示一个记号,来说明这个值是传给目标中哪个成员,第四个参数是要设置的值
uvm_config_db#(T)::get(uvm_component cntxt,string inst_name string field_name,inout T value);
第一个和第二个参数联合起来形成目标路径。第一个参数是uvm_component实例的指针,第二个参数是相对此实例的路径,第三个参数表示一个记号,来说明这个值是传给目标中哪个成员,第四个参数是要设置的值
set()函数和get()函数的第三个参数必须完全一致,get()函数中如果第一个参数被设置为this,那么第二个参数可以是一个字符串
在类定义时,添加参数#(type T=...)表示后期类在声明变量时,如果不指定参数类型,则默认采用T类型

使用场景:

interface传递

UVM的uvm_config_db使得接口的传递和获取彻底分离开来
在实现接口传递的过程中需要注意:
接口传递应该发生在run_test()之前。这保证了在进入build phase之前,virtual interface已经被传递到uvm_donfig_db中
用户应当把interface与virtual interface的声明区别开来。在传递过程中的类型应该为virtual interface,即实际接口的句柄
通过config_db机制的set函数设置virtual interface时,set函数的第一个参数为null,这种情况下,UVM会自动把第一个参数替换为uvm_root::get(),即uvm_top
变量设置
在各个test中,可以在build_phase对底层组件的变量加以配置,进而在环境例化之前完成配置,使得环境可以按照预期运行

object传递

将每个组件中的多个变量加以整合,首先放到一个uvm_object中,再对中心化的配置对象进行传递,会有利于整体环境的修改维护
使用建议
在使用set()/get()方法时,传递的参数类型应当上下保持一致。对于uvm_object等实例的传递,如果get类型和set类型不一致,应当首先通过$cast()完成类型转换,再对类型转换后的对象进行操作
尽量确保uvm_config_db::set()方法在相关配置组件创建前调用。

消息管理

消息方法

function void uvm_report_info(string id,string message,int verbosity = UVM_MEDIUM,string filename = "",int line = 0);
function void uvm_report_warning(string id,string message,int verbosity = UVM_MEDIUM,string filename = "",int line = 0);
function void uvm_report_error(string id,string message,int verbosity = UVM_LOW,string filename = "",int line = 0);
function void uvm_report_fatal(string id,string message,int verbosity = UVM_NONE,string filename = "",int line = 0);

四个消息函数有四个共同的信息,分别是严重级别,冗余度,消息ID,消息,文件名和 行号。冗余度:冗余度的设置如果等于或低于过滤的开关,那么该信息会打印出来,否则不会被打印出来,分为NONE,LOW,MEDIUM,HIGH,FULL,DEBUG六种冗余度,冗余度由低到高。冗余度为NONE时,只有NONE的信息可以被打印出来

消息处理

消息处理方式

Alt text
各严重级别消息处理方式
Alt text
用户也可以通过uvm_report_object类提供的方法进行配置

set_report_id_verbosity_hier("ID",verbosity);//可以指定ID进行余度过滤
uvm_root::get().set_report_id_verbosity_hier("ID",verbosity);/可以从顶层对ID进行过滤

打印消息
Alt text
消息打印函数

uvm_info("MYINFO1", $sformatf("val: %0d", val), UVM_LOW)
uvm_warning("MYWARN1", "This is a warning")
uvm_error("MYERR", "This is an error")
uvm_fatal("MYFATAL", "A fatal error has occurred")

消息用户在处理信息时可以使用回调函数实现更多功能

function bit report_hook(string id,string message,int verbosity = UVM_MEDIUM,string filename = "",int line = 0);
function bit report_info_hook(string id,string message,int verbosity = UVM_MEDIUM,string filename = "",int line = 0);
function bit report_error_hook(string id,string message,int verbosity = UVM_LOW,string filename = "",int line = 0);
function bit report_fatal_hook(string id,string message,int verbosity = UVM_NONE,string filename = "",int line = 0);
function bit report_warning_hook(string id,string message,int verbosity = UVM_NONE,string filename = "",int line = 0);
用户在调用回调函数时,会首先调用report_hook()函数,接下来才按照severity级别来选择更细致的回调函数report_SEVERITY_hook()