跳转至

输入查询内容

    本页内容

    copy(null) 现在计为错误;普通 copy 调用可保留

    影响范围

    可能传入 null 的 copy,或使用自定义 copier/递归策略。

    具体差异

    拷贝改由 uvm_copier 策略执行(m_copier.copy_object(this,rhs)),1.2 的 uvm_global_copy_map 循环引用防护由 copier 内部接管;递归策略(UVM_DEEP/SHALLOW/REFERENCE)由 copier 的 set_recursion_policy 控制。默认 copier 来自 uvm_coreservice_t::get_default_copier()。旧调用 obj.copy(rhs) 源码兼容(新参数有默认值),但 null rhs 现在计为 UVM_ERROR,可能影响 error 计数/门禁脚本。

    修改方案

    排查回归中对 copy(null) 的依赖;需要浅拷贝/引用拷贝语义的用 uvm_copier::set_recursion_policy

    已有的 dst.copy(src) 可继续使用。如果 src 在业务上允许为空,明确处理这个分支:

    if (src != null)
      dst.copy(src);
    

    这里只适用于“空源表示本次不更新”。若源对象本应存在,应修复对象创建或传递流程,不能加判空来掩盖缺失事务。

    兼容措施与范围:兼容措施不恢复 copy(null) 的旧诊断;保留有效对象拷贝,并明确空对象处理与递归策略。

    迁移后验证

    分别复制有效对象和 null;检查字段、嵌套对象身份和错误计数。null 路径应产生目标 OBJ/COPY 错误,不能被成功计数掩盖。

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

    已有实测与复现

    补充查阅

    扫描定位与记录结果

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

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

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

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

    源码与标准依据

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

    1. copy(null) 从 warning 变为 error,两版均提前返回

    VCS 内置 UVM-1.2:null 分支发出 NULLCP warning 后返回:uvm_object.svh:1063–1066

    VCS 内置 uvm-ieee-2020-2.0:对应分支发出 OBJ/COPY error 后返回:uvm_object.svh:957–960。变化会影响错误计数;不能仅凭调用能编译判断行为不变。

    2. 普通 copy(rhs) 调用仍可保留

    VCS 内置 UVM-1.2:旧声明只有 rhs 参数:uvm_object.svh:458

    VCS 内置 uvm-ieee-2020-2.0:新声明的 copier 参数默认是 null:uvm_object.svh:454。省略参数时,从 coreservice 取得默认 copier 并分派复制:uvm_object.svh:962–973

    补充定位

    VCS 内置 UVM-1.2uvm_object.svh:458(声明 copy(uvm_object rhs))、uvm_object.svh:1044(实现,null rhs 报 NULLCP warning 后忽略)

    VCS 内置 uvm-ieee-2020-2.0uvm_object.svh:454(声明 copy(uvm_object rhs, uvm_copier copier=null))、uvm_object.svh:953(实现,null rhs 报 uvm_error OBJ/COPY

    标准依据:IEEE 1800.2-2020 §5.3.8.1(copy)、§16.6(uvm_copier)

    标为“源码标注”或未注明原文核对的条款仅作定位;具体库行为以源码和实测为准。

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

    src/vcs-uvm-1.2/base/uvm_object.svh
      // classes. To copy the fields of a derived class, that class should override
      // the <do_copy> method.
    
      extern function void copy (uvm_object rhs);
    
    
      // Function: do_copy
      //
      // The ~do_copy~ method is the user-definable hook called by the <copy> method.
      // A derived class should override this method to include its fields in a <copy>
      // operation.
      //
      // A typical implementation is as follows:
      //
      //|  class mytype extends uvm_object;
      //|    ...
      //|    int f1;
      //|    function void do_copy (uvm_object rhs);
      //|      mytype rhs_;
    

    src/vcs-uvm-1.2/base/uvm_object.svh
    // copy
    // ----
    
    function void uvm_object::copy (uvm_object rhs);
      //For cycle checking
    `ifdef UVM_VCS_FGP
    
      thread_specific_object tobj;
      static uvm_fgp_thread_object#(thread_specific_object) fgp_thread_obj = new;
      tobj =fgp_thread_obj.get_wrapper();      
      `define UVM_GLOBAL_COPY_MAP tobj.uvm_global_copy_map
      `define UVM_VCS_DEPTH tobj.depth
    `else
      static int depth;
      `define UVM_GLOBAL_COPY_MAP uvm_global_copy_map
      `define UVM_VCS_DEPTH depth
    `endif
    
      if((rhs !=null)  && `UVM_GLOBAL_COPY_MAP.exists(rhs)) begin
        return;
      end
    
      if(rhs==null) begin
        uvm_report_warning("NULLCP", "A null object was supplied to copy; copy is ignored", UVM_NONE);
        return;
      end
    
      `UVM_GLOBAL_COPY_MAP[rhs]= this; 
      ++`UVM_VCS_DEPTH;
    
      __m_uvm_field_automation(rhs, UVM_COPY, "");
      do_copy(rhs);
    
      --`UVM_VCS_DEPTH;
      if(`UVM_VCS_DEPTH == 0) begin
        `UVM_GLOBAL_COPY_MAP.delete();
      end
    endfunction
    

    完整源码 · SHA256:5bacc747c3d5a16a0206864bd84eedf1aeff153a7152dcb0d0e40af208fbe4ec

    src/vcs-uvm-ieee-2020-2.0/base/uvm_object.svh
      // the <do_copy> method.
    
      // @uvm-ieee 1800.2-2020 auto 5.3.8.1
      extern function void copy (uvm_object rhs, uvm_copier copier=null);
    
    
      // Function -- NODOCS -- do_copy
      //
      // The ~do_copy~ method is the user-definable hook called by the <copy> method.
      // A derived class should override this method to include its fields in a <copy>
      // operation.
      //
      // A typical implementation is as follows:
      //
      //|  class mytype extends uvm_object;
      //|    ...
      //|    int f1;
      //|    function void do_copy (uvm_object rhs);
      //|      mytype rhs_;
    

    src/vcs-uvm-ieee-2020-2.0/base/uvm_object.svh
    // copy
    // ----
    
    function void uvm_object::copy (uvm_object rhs, uvm_copier copier=null);
    uvm_coreservice_t coreservice ;
    uvm_copier m_copier;
    
      if(rhs == null)  begin
        `uvm_error("OBJ/COPY","Passing a null object to be copied")
        return;
      end
    
      if(copier == null) begin
        coreservice = uvm_coreservice_t::get() ;
           m_copier = coreservice.get_default_copier() ;
     end
       else 
        m_copier = copier;
      // Copier is available. check depth as and flush it. Sec 5.3.8.1
        if(m_copier.get_active_object_depth() == 0) 
            m_copier.flush();
    
      m_copier.copy_object(this,rhs);
    endfunction
    
    
    // do_copy
    // -------
    

    完整源码 · SHA256:53c99f38f1ce6cb3c6a215858b84938d18eb858f9396d3dba281a32addb3c9c9

    术语解释 · 兼容配置

    返回Object / Factory · 迁移清单

    版本适用范围