目录
一、简要
在《UVM Field机制详解一:宏和用法介绍》中,简要介绍了UVM Field机制的使用方法和宏,在该章节,将深入解析Field行为是如何实现的,即宏定义的实际内容。
二、函数和宏的关系
总所周知,宏定义是为了使用便捷函数。那么为了理解宏定义的内容,就需要从函数中下手,他们是如何联系上的呢?
在上图中可以看到,函数是定义在uvm_object.svh文件中的,即在uvm_object class中定义的内置函数。所以理论上只要继承于uvm_object的类,均可以通过xx.aaa()的方式来调用这些函数(xx为类实例化后的名字,aaa为函数名)。
找到了函数的位置,就可以来研究一下函数的内容,用相对简单的copy来举例。
copy的实际行为在第1035行的__m_uvm_field_automation(rhs,UVM_COPY,"")。
这个函数是定义在uvm_object中的一个可重写函数,在文档中为空函数。
实际的使用就是用户在自定义的class中使用宏定义来重写该函数,注册宏又是如何实现重写的呢?
三、宏解析
宏定义在uvm_object_defines.svh文件中,可以看到,基本所有注册的函数,包括uvm_component_utils_begin等,还有注册类的函数,均定义在该文件中。
注册的常用方法为:
`uvm_object_utils_begin(test_class)
`uvm_object_int(aaa_int ,UVM_ALL_ON)
`uvm_object_string(bbb_string ,UVM_ALL_ON)
`uvm_object_enum(color_e,color_enum,UVM_ALL_ON | UVM_NOPRINT)
`uvm_object_utils_end
那么先搜寻一下`uvm_object_utils_begin(rhs)的定义内容。
和注册宏有关的是261行的`uvm_field_utils_begin(T)宏,其他的宏与field机制无关,可以不需要关心。另外,uvm_component_utils_begin的行为是调用了uvm_object_utils_begin实现注册行为的,所以本质上是一样的。
在`uvm_field_utils_begin(T)宏中,即对__m_uvm_field_automation的重定义的一个函数头。注册函数为重定义的实际内容,将每一个注册的成员补充进这个函数,最后调用`uvm_field_utils_end来结束函数。可以看下图的图示。
所以注册的过程就是重写__m_uvm_field_automation函数的过程,注册后调用copy, compare等函数的时候,就会用到重写的该函数,来实现成员的行为控制。
四、成员的注册行为
了解了utils_begin和utils_end的行为之后,来了解一下成员的注册宏是如何填充域的自动化函数的。
以最常用的`uvm_object_int来举例。
可以看到,在uvm_field_int中,核心参数是what__,这个参数可以参照上面的图2-2和图2-3,是在使用函数时传入的。如果使用copy,将会传入UVM_COPY,使用compare,将会传入UVM_COMPARE。所以注册就是定义了变量在使用函数时的实际行为。而注册时传入的ARG和FLAG在函数中也会有所运用。
简单看一下copy的行为。
copy行为非常简单,就是判断FLAG中是否带UVM_NOCOPY,如果没有带,将local_data中的对象值赋给当前对象。local_data__就是在copy时在括号中传入的tr对象,而当前对象则是执行copy行为的tr对象。
从这里以及后面的代码都可以看出,虽然在FLAG中既有表示功能开启的flag bit位,例如UVM_COPY,UVM_COMPARE等,也有表示功能关闭的flag bit位,比如UVM_NOCOPY和UVM_NOCOMPARE。但实际生效的是关闭的这个flag位,若该位使能,则表示功能关闭。所以理论上,传入FLAG为0,表示功能全部开启。
其他函数的实际行为,将再后文中另加详细解析。