跳转至

输入查询内容

    本页内容

    自定义打印、比较与录制:检查策略状态和输出

    影响范围

    自定义 printer/comparer/recorder,或将打印和比较日志作为 golden

    具体差异

    操作改由对应 policy 驱动;sprintcomparecopy 在 active depth 为 0 时执行各自 flush,不能推广为所有 recorder 调用均自动清理。自定义 policy 要核对新调用契约。默认策略建议经 set_default/get_default 访问;默认 printer 仍为 table printer,但内部行模型与格式生成已重写,文本黄金文件必须重新对照,不能假定输出逐字相同。

    修改方案

    保留业务 do_print/do_compare/do_record 钩子;其中调用的 printer/comparer/recorder API 分别按 M02-003 / M02-005 / M02-007 / M02-012 改写。每次独立对象操作核对策略状态,消息过滤按实际 comparer 发出的 MISCMP 路径配置;用返回值、输出内容和字段调用次数验证,不能只按日志数量判定成功。

    兼容措施与范围:业务 do_* 钩子可保留,其策略状态和报告行为仍按目标接口核对;packer 的部分兼容见 M02-001

    迁移后验证

    连续操作两个对象,检查状态没有串扰;同时比较返回值、输出内容和记录次数。不要把 recorder 当成与 sprint 相同的自动 flush 契约。

    记录本条结果M01-009 · 状态与证据

    已有实测与复现

    补充查阅

    扫描定位与记录结果

    有扫描规则,覆盖部分可识别写法。脚本检查名称、参数和部分 FLAG 表达式,并对少数直接声明关联使用点;未做完整类型解析或预处理,行为结果仍需验证。

    uv run tools/uvm_migration_scan.py <SoC代码目录> --rules S27
    

    核对命中对象及生效分支后,在条目清单记录修改与验证证据;扫描规则记录用于整理命中位置。

    扫描器下载、输入范围与报告说明

    源码与标准依据

    核查方式:源码与实测核对。实测仅覆盖本条所列场景。

    VCS 内置 UVM-1.2uvm_object.svh:913(print 对 uvm_default_printer==nullNULLPRINTER error,经 printer.knobs.mcd 输出)、uvm_object.svh:1120(compare 内直接报 MISCMP info)、uvm_object.svh:1350(record 内经 __m_uvm_field_automation(UVM_RECORD) 驱动)

    VCS 内置 uvm-ieee-2020-2.0uvm_object.svh:873–874uvm_printer::get_default() + printer.get_file(),NULLPRINTER 检查移除)、uvm_object.svh:884(sprint 顶层先 printer.flush())、uvm_object.svh:992(compare 委托 comparer.compare_object(),缺省 comparer 改由 uvm_comparer::get_default())、uvm_object.svh:1178(record 委托 recorder.record_object(get_name(), this)

    引用代码(高亮为引用行);上方行号链接可直接定位。

    src/vcs-uvm-1.2/base/uvm_object.svh
      if (printer==null)
        printer = uvm_default_printer;
      if (printer == null)
        `uvm_error("NULLPRINTER","uvm_default_printer is null")
      $fwrite(printer.knobs.mcd,sprint(printer)); 
    endfunction
    
    
    // sprint
    // ------
    
    function string uvm_object::sprint(uvm_printer printer=null);
      bit p;
    
      if(printer==null)
        printer = uvm_default_printer;
    
      // not at top-level, must be recursing into sub-object
      if(!printer.istop()) begin
    

    src/vcs-uvm-1.2/base/uvm_object.svh
        end
        else begin
          comparer.print_msg_object(this, rhs);
          uvm_report_info("MISCMP",
               $sformatf("%0d Miscompare(s) for object %s@%0d vs. null", 
               comparer.result, 
               __m_uvm_status_container.scope.get(),
                this.get_inst_id()),
                __m_uvm_status_container.comparer.verbosity);
          done = 1;
        end
      end
    
      if(!done && comparer.compare_map.exists(rhs)) begin
        if(comparer.compare_map[rhs] != this) begin
          comparer.print_msg_object(this, comparer.compare_map[rhs]);
        end 
        done = 1;  //don't do any more work after this case, but do cleanup
      end
    

    src/vcs-uvm-1.2/base/uvm_object.svh
      __m_uvm_status_container.recorder = recorder;
      recorder.recording_depth++;
      __m_uvm_field_automation(null, UVM_RECORD, "");
      do_record(recorder);
    
      recorder.recording_depth--;
    
      //if(recorder.recording_depth==0) begin
      //  recorder.tr_handle = 0;
      //end
    endfunction
    
    
    // do_record (virtual)
    // ---------
    
    function void uvm_object::do_record (uvm_recorder recorder);
      return;
    

    完整源码 · SHA256:5bacc747c3d5a16a0206864bd84eedf1aeff153a7152dcb0d0e40af208fbe4ec

    src/vcs-uvm-ieee-2020-2.0/base/uvm_object.svh
    // -----
    
    function void uvm_object::print(uvm_printer printer=null);
      if (printer==null) printer = uvm_printer::get_default();
      $fwrite(printer.get_file(),sprint(printer)); 
    endfunction
    
    
    // sprint
    // ------
    
    function string uvm_object::sprint(uvm_printer printer=null);
      string name;
    
      if(printer==null) printer = uvm_printer::get_default();
      if (printer.get_active_object_depth() == 0) begin
        printer.flush() ;
        name  = printer.get_root_enabled() ? get_full_name() : get_name();
      end
      else begin
        name  = get_name();
      end
    
      printer.print_object(name,this);
    
      return printer.emit();
    
    endfunction
    

    src/vcs-uvm-ieee-2020-2.0/base/uvm_object.svh
      if (comparer == null) comparer = uvm_comparer::get_default();
      if (comparer.get_active_object_depth() == 0) 
        comparer.flush() ;
      compare = comparer.compare_object(get_name(),this,rhs);
    
    endfunction
    
    
    // do_compare
    // ----------
    
    function bit  uvm_object::do_compare (uvm_object rhs,
                                          uvm_comparer comparer);
      return 1;
    endfunction
    
    
    // __m_uvm_field_automation
    // ------------------
    

    src/vcs-uvm-ieee-2020-2.0/base/uvm_object.svh
      if(recorder == null)
        return;
    
      recorder.record_object(get_name(), this);
    endfunction
    
    
    // do_record (virtual)
    // ---------
    
    function void uvm_object::do_record (uvm_recorder recorder);
      return;
    endfunction
    
    
    // m_get_report_object
    // -------------------
    
    function uvm_report_object uvm_object::m_get_report_object();
    

    完整源码 · SHA256:53c99f38f1ce6cb3c6a215858b84938d18eb858f9396d3dba281a32addb3c9c9

    术语解释 · 兼容配置

    pack 位流格式改变(M02-001) · 删除无效的打印宽度配置(M02-003) · 自定义比较(M02-005) · 自定义 recorder 的对象递归与文本输出(M02-007) · 重写 recorder、stream、database 方法时同步句柄类型(M02-012)

    返回Object / Factory · 迁移清单

    版本适用范围