report机制可以实现对信息打印的精确控制。下面分点讲解,并且均是在uvm_component组件中使用信息宏。(uvm_object中使用原理相同)
下面以`uvm_error(“ID”,”message”)来说明:
`define uvm_warning(ID,MSG) \ begin \ if
(uvm_report_enabled(UVM_NONE,UVM_WARNING,ID)) \ uvm_report_warning (ID, MSG,
UVM_NONE, `uvm_file, `uvm_line); \ end
首先介绍在UVM中非常重要的几个概念(1)verbosity,(2)存在severity(3)action。
verbosity可以这么理解:反应信息需要被打印的过滤程度,主要有下面几种类型
typedef enum { UVM_NONE = 0, UVM_LOW = 100, UVM_MEDIUM = 200, UVM_HIGH = 300,
UVM_FULL = 400, UVM_DEBUG = 500 } uvm_verbosity;
verbosity值越大,越容易被过滤掉
与verboisty相对应的是信息的安全级别(severity),主要有下面几种
typedef enum bit [1:0] { UVM_INFO, UVM_WARNING, UVM_ERROR, UVM_FATAL }
uvm_severity;
severity反应的是信息的安全级别,不同的安全级别有不同的行为,行为的分类主要有下面几种
行为类别主要是仿真器应该执行怎么样的操作。 typedef enum { UVM_NO_ACTION ='b0000000, UVM_DISPLAY =
'b0000001, UVM_LOG = 'b0000010, UVM_COUNT = 'b0000100, UVM_EXIT = 'b0001000,
UVM_CALL_HOOK ='b0010000, UVM_STOP = 'b0100000, UVM_RM_RECORD ='b1000000 }
uvm_action_type;
下面正式开讲,首先讲解uvm_report_enable。这个方法主要是判断这个message是否可以被执行打印。
//uvm_report_object.svh function int uvm_report_enabled(int verbosity,
uvm_severity severity = UVM_INFO, string id = ""); if
(get_report_verbosity_level(severity, id) < verbosity) return 0; return 1;
endfunction function int get_report_verbosity_level(uvm_severity
severity=UVM_INFO, string id=""); return m_rh.get_verbosity_level(severity,
id); endfunction //其中m_rh是uvm_report_handle的一个句柄。 uvm_report_handler m_rh;
function new(string name = ""); super.new(name); m_rh =
uvm_report_handler::type_id::create(name); endfunction
//发现每个uvm_component在创建的时候又会带有自己的m_rh. function int
get_verbosity_level(uvm_severity severity=UVM_INFO, string id="" );
uvm_id_verbosities_array array; if(severity_id_verbosities.exists(severity))
begin array = severity_id_verbosities[severity]; if(array.exists(id)) begin
return array.get(id); end end if(id_verbosities.exists(id)) begin return
id_verbosities.get(id); end return m_max_verbosity_level; endfunction
所以最终起作用的是uvm_report_handle的get_verbosity_level函数。这里面用到几个重要的变量(联合数组)
typedef uvm_pool#(string, int) uvm_id_verbosities_array;//核心是联合数组 int
pool[string] uvm_id_verbosities_array id_verbosities;// //核心是联合数组 int
pool[string],存放每个ID的verbosity uvm_id_verbosities_array
severity_id_verbosities[uvm_severity];// 核心是联合数组 int
pool[string],存放每个severity对包含的不同ID的verbosity int m_max_verbosity_level;
//默认的verbosity
上述所有的string表示“”ID“”。存储的值是int类型的verbosity值(m_max_verbosity_level默认是UVM_MEDIEM,这是由于每个组件例化的时候都带有一个uvm_report_handle的句柄,uvm_report_handle在例化的时候将m_max_verbosity_level默认是UVM_MEDIEM,方法set_verbosity_level可以改变这个变量值,在命令行同时可以改变+UVM_VERBOSITY=xxxx)
因此对于uvm_error。传入的verbosity是UVM_NONE,而这个ID默认存储的是UVM_MEDIUM,UVM_MEDIUM>UVM_NONE的。所以调用uvm_report_object中的uvm_report_enable函数返回1。
变量id_verbosities可以使用set_id_verbosity方法增加元素变量severity_id_verbosities[uvm_severity]可以使用set_
severity_id_verbosity方法增加元素变量。
所以正常来说get_verbosity_level返回的是m_max_verbosity_level,因为severity_id_verbosities[uvm_severity]和id_verbosities是空的。
severity_id_verbosities[uvm_severity]>id_verbosities>m_max_verbosity_level(优先级)
下面将4个相关的宏全部列出来
`define uvm_info(ID,MSG,VERBOSITY) \ begin \ if
(uvm_report_enabled(VERBOSITY,UVM_INFO,ID)) \ uvm_report_info (ID, MSG,
VERBOSITY, `uvm_file, `uvm_line); \ end `define uvm_warning(ID,MSG) \ begin \
if (uvm_report_enabled(UVM_NONE,UVM_WARNING,ID)) \ uvm_report_warning (ID, MSG,
UVM_NONE, `uvm_file, `uvm_line); \ end `define uvm_error(ID,MSG) \ begin \ if
(uvm_report_enabled(UVM_NONE,UVM_ERROR,ID)) \ uvm_report_error (ID, MSG,
UVM_NONE, `uvm_file, `uvm_line); \ end `define uvm_fatal(ID,MSG) \ begin \ if
(uvm_report_enabled(UVM_NONE,UVM_FATAL,ID)) \ uvm_report_fatal (ID, MSG,
UVM_NONE, `uvm_file, `uvm_line); \ end
总结:在调用`uvm_error(“ID”,“message”)时,会向调用uvm_report_handle中的get_report_level得到message被设置的verbosity,只有到这个verbosity>=传入的的verbosity时,这个条message才是enable打印的。对于uvm_error/warning/fatal。传入的verbosity是UVM_NONE。因此对于这3个message,都是enable的。对于uvm_info,则是需要判断的。