跳转至

输入查询内容

    本页内容

    内置复位测试按 has_reset() 跳过字段

    影响范围

    自研复位测试依赖自动 NO_REG_HW_RESET_TEST 资源或多层 block 遍历。

    具体差异

    不能声称覆盖等价。2.0 对无 reset 字段临时设置 UVM_NO_CHECK,并在 mirror 后恢复;1.2 默认代码并不消费 configure 自动写入的普通字段级资源,旧条件扩展还使用不同的字段名拼接。遍历也从 map 和递归全后代改为本地 reg + 直接子块递归。三层 block 探针的叶寄存器 mirror 次数为 2 / 1,无 reset 字段在 mirror 中关闭比较的标记为 0 / 1,结束后均恢复 UVM_CHECK。用户显式的 block/reg 排除保留,但字段级排除应逐项核对名称与开关。

    修改方案

    自研复位测试用 field.has_reset() 判断是否存在 reset 值;镜像比较前保存原 get_compare(),对无 reset 字段临时 set_compare(UVM_NO_CHECK),比较后恢复原值。保留用户明确登记的 block/reg 排除,字段级排除单独核对实际名称。递归遍历采用每层本地寄存器加直接子块递归,避免叶寄存器重复 mirror

    兼容措施与范围:兼容措施不恢复旧复位测试遍历与字段比较规则;原 block/reg 排除保留,字段跳过和访问次数须核对。

    迁移后验证

    同时包含有/无 reset 字段和三层 block,检查每个目标的访问次数、check 开关及结束后恢复值。

    记录本条结果M07-004 · 状态与证据

    已有实测与复现

    补充查阅

    扫描定位与记录结果

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

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

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

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

    源码与标准依据

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

    VCS 内置 UVM-1.2uvm_reg_field.svh:829configurehas_reset==0 时自动 uvm_resource_db::set({...}, "NO_REG_HW_RESET_TEST", 1));uvm_reg_hw_reset_seq.svh:94/uvm_reg_hw_reset_seq.svh:129/uvm_reg_hw_reset_seq.svh:139(seq 查询该 resource 跳过)

    VCS 内置 uvm-ieee-2020-2.0uvm_reg_field.svh:433configure 不再写 resource);uvm_reg_hw_reset_seq.svh:113/uvm_reg_hw_reset_seq.svh:129(改用 regs[ridx].has_reset()==0fields[fidx].has_reset()==0 直接判断);寄存器遍历也改为直接 blk.get_registers(regs)

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

    src/vcs-uvm-1.2/reg/uvm_reg_field.svh
       if (has_reset)
          set_reset(reset);
       else
          uvm_resource_db#(bit)::set({"REG::", get_full_name()},
                                     "NO_REG_HW_RESET_TEST", 1);
    
       m_parent.add_field(this);
    
       if (!m_policy_names.exists(m_access)) begin
          `uvm_error("RegModel", {"Access policy '",access,
           "' for field '",get_full_name(),"' is not defined. Setting to RW"})
          m_access = "RW";
       end
    
       if (size > m_max_size)
          m_max_size = size;
    
       // Ignore is_rand if the field is known not to be writeable
    

    完整源码 · SHA256:203f137cd6cc544089313f20cbc64046691beb899d7596db93e03b9d1968d3f2

    src/vcs-uvm-1.2/reg/sequences/uvm_reg_hw_reset_seq.svh
          if (uvm_resource_db#(bit)::get_by_name({"REG::",blk.get_full_name()},
                                                 "NO_REG_TESTS", 0) != null ||
              uvm_resource_db#(bit)::get_by_name({"REG::",blk.get_full_name()},
                                                 "NO_REG_HW_RESET_TEST", 0) != null ) begin
                return;
    
          end
    
    
          blk.get_maps(maps);
          // Iterate over all maps defined for the RegModel block
    
          foreach (maps[d]) begin
            uvm_reg regs[$];
    `ifdef UVM_REG_FIELD_LEVEL_ATTRIBUTE
           uvm_reg_field fields[$];
           uvm_check_e fields_to_suppress[uvm_reg_field];
    `endif
            maps[d].get_submaps(sub_maps);
    

    src/vcs-uvm-1.2/reg/sequences/uvm_reg_hw_reset_seq.svh
              if (uvm_resource_db#(bit)::get_by_name({"REG::",regs[i].get_full_name()},
                                                     "NO_REG_TESTS", 0) != null ||
                  uvm_resource_db#(bit)::get_by_name({"REG::",regs[i].get_full_name()},
                                                     "NO_REG_HW_RESET_TEST", 0) != null )
                  continue;
    
    `ifdef UVM_REG_FIELD_LEVEL_ATTRIBUTE
              // Need to iterate over fields to mark fields for not comparing
              regs[i].get_fields(fields);
              foreach (fields[k]) begin
                  if (uvm_resource_db#(bit)::get_by_name({"REG::",fields[k].get_full_name()},
                                                   {fields[k].get_full_name(), "_NO_REG_TESTS"}, 0) != null ||
                         uvm_resource_db#(bit)::get_by_name({"REG::",fields[k].get_full_name()},
                                                   { fields[k].get_full_name(), "_NO_REG_HW_RESET_TEST"}, 0) != null ) begin
                      fields_to_suppress[fields[k]] = fields[k].get_compare();
                      fields[k].set_compare(UVM_NO_CHECK);
                  end
              end
              fields.delete();
    `endif
    
              `uvm_info(get_type_name(),
                        $sformatf("Verifying reset value of register %s in map \"%s\"...",
                        regs[i].get_full_name(), maps[d].get_full_name()), UVM_LOW);
    
              regs[i].mirror(status, UVM_CHECK, UVM_FRONTDOOR, maps[d], this);
    
              if (status != UVM_IS_OK) begin
                 `uvm_error(get_type_name(),
    

    完整源码 · SHA256:058d40ffb49eb296a7565be8f30f456cff6a12c96a7bf8624cf6eb027f6713e0

    src/vcs-uvm-ieee-2020-2.0/reg/uvm_reg_field.svh
    // configure
    
    function void uvm_reg_field::configure(uvm_reg        parent,
                                           int unsigned   size,
                                           int unsigned   lsb_pos,
                                           string         access,
                                           bit            volatile,
                                           uvm_reg_data_t reset,
                                           bit            has_reset,
                                           bit            is_rand,
                                           bit            individually_accessible); 
       m_parent = parent;
       if (size == 0) begin
          `uvm_error("RegModel",
             $sformatf("Field \"%s\" cannot have 0 bits", get_full_name()))
          size = 1;
       end
    

    完整源码 · SHA256:08e4cb573f5f6f23fb1c7ae019ed2b4f7f08c9631878d5f88df2464858fa5bbb

    src/vcs-uvm-ieee-2020-2.0/reg/sequences/uvm_reg_hw_reset_seq.svh
          foreach(regs[ridx]) begin
             if (uvm_resource_db#(bit)::get_by_name({"REG::",regs[ridx].get_full_name()},
                                                    "NO_REG_TESTS", 0) != null ||
                                                    regs[ridx].has_reset() == 0 ||
                                                    uvm_resource_db#(bit)::get_by_name({"REG::",regs[ridx].get_full_name()},
                                                    "NO_REG_HW_RESET_TEST", 0) != null )
                continue;
    
             begin
                uvm_reg_map rm[$];
                uvm_status_e status;
                uvm_reg_field fields[$];
                uvm_check_e field_check_restore[uvm_reg_field];
    
                regs[ridx].get_maps(rm);
    
                regs[ridx].get_fields(fields);
    
                foreach(fields[fidx]) begin
                   if (fields[fidx].has_reset() == 0 ||
                       fields[fidx].get_compare() == UVM_NO_CHECK || 
                       uvm_resource_db#(bit)::get_by_name({"REG::",fields[fidx].get_full_name()},
                                                           "NO_REG_HW_RESET_TEST", 0) != null) begin
                      field_check_restore[fields[fidx]] = fields[fidx].get_compare();  
                      fields[fidx].set_compare(UVM_NO_CHECK);
                   end
                end  
                // if there are some fields to check
                if(fields.size() != field_check_restore.size()) begin
                   foreach(rm[midx]) begin
                      `uvm_info(get_type_name(),
                         $sformatf("Verifying reset value of register %s in map \"%s\"...",
                            regs[ridx].get_full_name(), rm[midx].get_full_name()), UVM_LOW)
    
                      regs[ridx].mirror(status, UVM_CHECK, UVM_FRONTDOOR, rm[midx], this);
    

    完整源码 · SHA256:27bcce25f7670ebe5d57b262a4794b24e5b80dd3df6807dd4095b19199d9cea1

    术语解释 · 兼容配置

    返回RAL(寄存器模型) · 迁移清单

    版本适用范围