跳转至

输入查询内容

    本页内容

    支持 byte enable 的相邻字段访问仍可能退化为整寄存器访问(S14)

    已复现的目标库问题

    目标库字段写粒度问题已复现;显式字段访问在固定映射场景通过。

    影响范围

    存在 byte-enable、W1C/RC 或硬件自主更新的相邻字段时,不能把整寄存器访问视为等价。

    具体差异

    8 位字段与其他字段共用 32 位总线 word 时,即使 individually_accessible 和 supports_byte_enable 都为 1,2.0 仍发 RegModel warning 并走整寄存器访问。示例的 64 位寄存器字段写从单笔 byte_en=1 变为两笔全字节写;若其他字段的硬件值已偏离镜像,整寄存器写可能覆盖该值。

    修改方案

    有 W1C、RC 或硬件自主更新字段的寄存器必须核对真实访问粒度。可使用显式 bus sequence 或经过验证的用户 frontdoor 实现 byte strobe,访问成功后只预测目标字段;+DIRECT_FIELD_WRITE 演示该固定映射场景。禁止仅屏蔽 warning 后将整寄存器访问视为等价。

    兼容措施与范围:兼容措施不恢复字段访问粒度;替代路径仍须核对 byte strobe、相邻字段副作用与预测。

    已知限制KI-004

    迁移后验证

    预置与镜像不同的相邻硬件值,执行目标字段写并记录每拍 byte strobe;只允许目标字段变化,不能靠 RegModel warning 被屏蔽来核销。

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

    已有实测与复现

    补充查阅

    扫描定位与记录结果

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

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

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

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

    源码与标准依据

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

    证据tests/uvm_review/reg_access_probe.sv,矩阵同时检查字段写 beat 数和相邻硬件值。

    VCS 内置 UVM-1.2uvm_reg_field.svh:1745–1748(支持 byte enable 即允许独立访问)

    VCS 内置 uvm-ieee-2020-2.0uvm_reg_field.svh:1409–1489(还要求字段在总线宽度内独占)

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

    src/vcs-uvm-1.2/reg/uvm_reg_field.svh
       end
    
       begin
         uvm_reg_map system_map = local_map.get_root_map();
         uvm_reg_adapter adapter = system_map.get_adapter();
         if (adapter.supports_byte_enable)
           return 1;
       end
    
       begin
         int fld_idx;
         int bus_width = local_map.get_n_bytes();
         uvm_reg_field fields[$];
         bit sole_field;
    
         m_parent.get_fields(fields);
    
         if (fields.size() == 1) begin
            sole_field = 1;
    

    完整源码 · SHA256:203f137cd6cc544089313f20cbc64046691beb899d7596db93e03b9d1968d3f2

    src/vcs-uvm-ieee-2020-2.0/reg/uvm_reg_field.svh
                        get_name(), "' because register '", m_parent.get_full_name(), "' has a user-defined front-door. Accessing complete register instead."})
          return 0;
       end
    
       begin
         uvm_reg_map system_map = local_map.get_root_map();
         uvm_reg_adapter adapter = system_map.get_adapter();
         if ((adapter != null) && !adapter.supports_byte_enable) begin
           `uvm_warning("RegModel", 
                        {"Target bus does not support byte enable, field '", get_full_name(),
                         ". Accessing complete register instead."})
           return 0;
         end
       end
    
       begin
         int fld_idx;
         int bus_width = local_map.get_n_bytes();
         uvm_reg_field fields[$];
    
         m_parent.get_fields(fields);
    
         if (fields.size() == 1) begin
            return 1;
         end
         else begin
            int prev_lsb,this_lsb,next_lsb; 
            int prev_sz,this_sz,next_sz; 
            int bus_sz = bus_width*8;
    
            foreach (fields[i]) begin
               if (fields[i] == this) begin
                  fld_idx = i;
                  break;
               end
            end
    
            this_lsb = fields[fld_idx].get_lsb_pos();
            this_sz  = fields[fld_idx].get_n_bits();
    
            if (fld_idx>0) begin
              prev_lsb = fields[fld_idx-1].get_lsb_pos();
              prev_sz  = fields[fld_idx-1].get_n_bits();
            end
    
            if (fld_idx < fields.size()-1) begin
              next_lsb = fields[fld_idx+1].get_lsb_pos();
              next_sz  = fields[fld_idx+1].get_n_bits();
            end
    
            // if first field in register
            if (fld_idx == 0 &&
               ((next_lsb % bus_sz) == 0 ||
                (next_lsb - this_sz) > (next_lsb % bus_sz)))
               return 1;
    
            // if last field in register
            else if (fld_idx == (fields.size()-1) &&
                ((this_lsb % bus_sz) == 0 ||
                 (this_lsb - (prev_lsb + prev_sz)) >= (this_lsb % bus_sz)))
               return 1;
    
            // if somewhere in between
            else begin
               if ((this_lsb % bus_sz) == 0) begin
                  if ((next_lsb % bus_sz) == 0 ||
                      (next_lsb - (this_lsb + this_sz)) >= (next_lsb % bus_sz))
                      return 1;
               end 
               else begin
                  if ( (next_lsb - (this_lsb + this_sz)) >= (next_lsb % bus_sz) &&
                      ((this_lsb - (prev_lsb + prev_sz)) >= (this_lsb % bus_sz)) )
                     return 1;
               end
            end
         end
       end
    
       `uvm_warning("RegModel", 
           {"Field '", get_full_name(),"' is not the only field within the entire bus width. ",
           "Individual field access will not be available. ",
           "Accessing complete register instead."})
    
       return 0;
    

    完整源码 · SHA256:08e4cb573f5f6f23fb1c7ae019ed2b4f7f08c9631878d5f88df2464858fa5bbb

    术语解释 · 兼容配置

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

    版本适用范围