UVM基础之---------uvm report 机制分析


uvm 中的信息报告机制相对来说比较简单,功能上来说主要分为两部分:

第一通过ID对component的信息报告冗余级别进行控制,针对每个冗余级别进行不同的行为控制。这部分工作主要由uvm_report_hander来实现:
     主要涉及到的方法有get_report_verbosity_level(severity, id)/get_report_action(severity,id) == uvm_action'(UVM_NO_ACTION)
第二是对message进行格式化的输出,这部分工作主要由uvm_report_server来实现
      主要涉及到的方法有message_compose

我们通过一个`uvm_error宏的执行进行分析,
    `uvm_error(“driver”,  “the config object is null”) 
这是一个在TB中调用的uvm宏,主要接收两个参数 ID和要打印的MSG,这个宏在 uvm_message_defines.svh中进行定义,具体定义如下:

140 `define uvm_error(ID,MSG)  \
141    begin  \
142      if (uvm_report_enabled(UVM_NONE,UVM_ERROR,ID))  \
143        uvm_report_error (ID, MSG, UVM_NONE, `uvm_file, `uvm_line);  \
144    end

首先调用的是uvm_report_enabled函数,主要目的是为了检查这个message是否允许输出。这个函数有两个版本, 假如是在一 个 component中调用uvm_error 宏的话,那么使用的是这个 component自己的函数, 而这个函数是在uvm_report_object中定义的:
447   function int uvm_report_enabled(int verbosity,
448                           uvm_severity severity=UVM_INFO, string id="");
449     if (get_report_verbosity_level(severity, id) < verbosity ||                            //检查对应severity,id的verbosity(冗余级别)是否大于允许输出的verbosity
450         get_report_action(severity,id) == uvm_action'(UVM_NO_ACTION))    //检查对应severity,id的action是否是UVM_NO_ACTION
451       return 0;
452     else
453       return 1;
454   endfunction
假如是在一个 sequence 中或者是一个派生自 uvm_object 的类中使用这个宏的 话,调用的是全局的函数
115 function bit uvm_report_enabled (int verbosity,
116                                  uvm_severity severity=UVM_INFO, string id="");
117   uvm_root top;
118   top = uvm_root::get();
119   return top.uvm_report_enabled(verbosity,severity,id);
120  endfunction

get_report_verbosity_level 的定义如下:  m_rh 是一个 uvm_report_handler 类型的变量,它会在每个 component 实例化的
时候被实例化,也就是说,每个 component 对应一个 m_rh,此变量用于记录这个 component 的一些报告信息, 如是否单独对此 component 设置了报告冗余度级别
(verbosity_lever) 。 get_report_verbosity_level 这个函数最终调用的是 uvm_report_handler的get_verbosity_level函数。

  81 class uvm_report_object extends uvm_object;
  82
  83   uvm_report_handler m_rh;
       …
  90   function new(string name = "");
  91     super.new(name);
  92     m_rh = new();
  93   endfunction
       …
413   function int get_report_verbosity_level(uvm_severity severity=UVM_INFO, string id="");
414     return m_rh.get_verbosity_level(severity, id);
415   endfunction
       …
539 endclas

下面简单的分析一下在uvm_report_handler中用到的get_verbosity_level函数,我们可以从中学到一些对数组的控制方式:
    55 class uvm_report_handler;
       …
236   function int get_verbosity_level(uvm_severity severity=UVM_INFO, string id="" );
237
238     uvm_id_verbosities_array array;
239     if(severity_id_verbosities.exists(severity)) begin           //首先判断severity_id_verbosities(联合数组,索引就是severity)中是否存在与serverity对应的记录
240       array = severity_id_verbosities[severity];                    //这个联合数组返回的是一个uvm_id_verbosities_array,而这个array是uvm_pool的一个实例,
241       if(array.exists(id)) begin                                              //这个uvm_id_verbosities_array的索引就是对应的message_id,而内容则是这个message_id的冗余整数
242         return array.get(id);                                                   //现在的问题是,这个severity_id_verbosities在哪里被写入??
243       end
244     end
245
246     if(id_verbosities.exists(id)) begin                                //id_verbosities是一个uvm_id_verbosities_array类型的变量
247       return id_verbosities.get(id);                                     //索引就是对应的message_id,而内容则是这个message_id的冗余整数
248     end                                                                               //同样的问题,这个id_verbosities在何时被写入??
249
250     return m_max_verbosity_level;
251
252   endfunction
       …
622 endclass : uvm_report_handle


对uvm_action和file handle的处理跟get_verbosity_level相类似,这里就不再进行分析,现在我们分析在上面代码分析中提到的两个问题:

   1. 这个severity_id_verbosities在哪里被写入?我们直接分析uvm_report_handler的code,因为前面提到了,这部分工作是有handler来实现和管理的:
  function void set_severity_id_verbosity(uvm_severity severity,
                                       string id,
                                       int verbosity);
    if(!severity_id_verbosities.exists(severity))
      severity_id_verbosities[severity] = new;
    severity_id_verbosities[severity].add(id,verbosity);
  endfunction

   2. id_verbosities在何时被写入?
  function void set_id_verbosity(input string id, input int verbosity);
    id_verbosities.add(id, verbosity);
  endfunction

分析上面的代码可以知道这里面set_severity_id_verbosity 要比set_id_verbosity的优先级要高。

我们前面说过,对message进行格式化的输出,这部分工作主要由uvm_report_server来实现,所以uvm_report_error经过传递,最终会调用uvm_report_server中的report函数,这里面需要提一下的是uvm_report_server是单实例的,在这里重申一下uvm_report机制几个类之间的关系, report—object和report_handler的关系是一 一对应的,当然也可以多个report_object对应一个report_handler(set_report_handler).handler到server的关系是多对一。

243   virtual function void report(
244       uvm_severity severity,
245       string name,
246       string id,
247         string message,
248       int verbosity_level,
249       string filename,
250       int line,
251       uvm_report_object client
252       );
253     string m;
254     uvm_action a;
255     UVM_FILE f;
256     bit report_ok;
257     uvm_report_handler rh;
258
259     rh = client.get_report_handler();  // 再次拿到uvm_component的uvm_report_hander的实例指针,目的是为了后面再次进行uvm_report_enabled检查,以及拿到在uvm_report_handler中的file_handle
260
261     // filter based on verbosity level
262 

273     f = rh.get_file_handle(severity, id);
274
275     // The hooks can do additional filtering.  If the hook function
276     // return 1 then continue processing the report.  If the hook
277     // returns 0 then skip processing the  report.
278
279     if(a & UVM_CALL_HOOK)
280       report_ok = rh.run_hooks(client, severity, id,
281                               message, verbosity_level, filename, line);                //调用run_hooks函数再次确认是否进行打印信息,run_hooks在uvm_report_handler中进行定义,调用uvm_report_object中定义的report_info_hook/report_warning_hook/report_error_hook/report_fatal_hook函数,可以在继承uvm_component的时候对这些hook进行重载,今儿实现对message的控制。

282     else
283       report_ok = 1;

285     if(report_ok)
286        report_ok = uvm_report_catcher::process_all_report_catchers(             //这是一个uvm_callback类, 它的主要用处就是在真正 的打印信息之前可以再次控制要打印的信息,每个uvm_catcher都要实现一个catch的函数!
287                      this, client, severity, name, id, message,
288                      verbosity_level, a, filename, line);
289
290     if(report_ok) begin
291       m = compose_message(severity, name, id, message, filename, line);
292       process_report(severity, name, id, message, a, f, filename, 



这个是在uvm_catcher中的process_report_catcher函数:

  local function int process_report_catcher();
    action_e act;
    act = this.catch();
    if(act == UNKNOWN_ACTION)
      this.uvm_report_error("RPTCTHR", {"uvm_report_this.catch() in catcher instance "this.get_name(), " must return THROW or CAUGHT"}, UVM_NONE, `uvm_file`uvm_line);
    if(m_debug_flags & DO_NOT_MODIFY) begin
      m_modified_severity    = m_orig_severity;
      m_modified_id          = m_orig_id;
      m_modified_verbosity   = m_orig_verbosity;
      m_modified_action      = m_orig_action;
      m_modified_message     = m_orig_message;
    end     
    if(act == CAUGHT  && !(m_debug_flags & DO_NOT_CATCH)) begin
      return 0;
    end  
    return 1;
  endfunction  








转载于:https://www.cnblogs.com/bob62/p/3876600.html

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
UVM工厂机制是一种用于创建和管理UVM组件和对象的机制。它通过使用UVM工厂类(uvm_factory)来实现。\[1\]该工厂类是一个独特的对象,用于注册和创建UVM组件和对象。在UVM中,组件和对象的注册是通过使用宏来实现的,分别是uvm_component_utils和`uvm_object_utils。\[2\]这些宏将组件和对象注册到工厂中,以便在需要时可以通过工厂来创建它们。 使用UVM工厂机制创建组件和对象有两种方法。一种是通过继承uvm_component类或uvm_object类,并在类内重载方法来实现。这种方法本质上是借用工厂对象来创建组件和对象。\[1\]另一种方法是直接使用工厂方法来创建组件和对象。这需要使用全局唯一的uvm_factory类对象factory来调用工厂方法,并使用$cast进行类型转换。\[3\] 总之,UVM工厂机制提供了一种方便的方式来注册和创建UVM组件和对象,使得它们可以在需要时动态地创建和使用。 #### 引用[.reference_title] - *1* *3* [UVM:factory 机制](https://blog.csdn.net/Starry__/article/details/122930959)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [UVM-工厂机制(factory)](https://blog.csdn.net/sinat_41774721/article/details/121763596)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值