跳转至

输入查询内容

    本页内容

    uvm_reg_backdoor 变为抽象类;wait_for_change 由 local 变 public

    影响范围

    直接构造 uvm_reg_backdoor 基类或扩展 wait_for_change。

    具体差异

    2.0 中直接 new 抽象基类会编译失败;经 abstract registry create 则可编译,但无具体 override 时报告运行错误,见 M01-006。wait_for_change 去掉 local 限定,目标实现允许派生类覆盖该钩子;这是保留的实现能力,不应据此当成新增 IEEE 标准 API。

    修改方案

    基类句柄可保留,new 的对象改为具体派生 backdoor。派生类实现 write(uvm_reg_item rw) 以及 read_func(rw) 或 read(rw),执行真实硬件访问并设置 status;不能只声明空子类绕过抽象类错误,基类默认 write/read_func 会报 fatal。将实例通过 rg.set_backdoor(bd) 挂到寄存器,使用 factory 时注册具体类型并检查 override 后的实际对象。需要 codec/callback 的访问按 M07-023 保留回调链。

    旧代码直接构造基类:

    uvm_reg_backdoor bd = new("bd");
    

    该声明在 1.2 可编译,但基类没有可用的默认读写实现;目标构造时即失败。将实例换成执行实际访问的具体类,基类句柄可以保留。下面用 interface 中的 32 位存储变量演示读写;类和 interface 声明放在模块外,先 include uvm_macros.svh 并 import uvm_pkg::*

    interface storage_if;
      bit [31:0] value;
    endinterface
    
    class storage_backdoor extends uvm_reg_backdoor;
      virtual storage_if vif;
      function new(string name = "storage_backdoor");
        super.new(name);
      endfunction
      virtual task write(uvm_reg_item rw);
        do_pre_write(rw);
        if (vif == null) rw.status = UVM_NOT_OK;
        else begin
          vif.value = rw.value[0];
          rw.status = UVM_IS_OK;
        end
        do_post_write(rw);
      endtask
      virtual function void read_func(uvm_reg_item rw);
        if (vif == null) rw.status = UVM_NOT_OK;
        else begin
          rw.value[0] = vif.value;
          rw.status = UVM_IS_OK;
        end
      endfunction
    endclass
    

    write 显式调用前后回调;继承的 read 已调用 do_pre_read → read_func → do_post_read,因此此处 read_func 只读数据并设置 status,避免重复回调。若改为 override 整个 read task,则自行保留这条调用链。Codec 的迁移仍按 M07-023 处理。

    在模块中实例化 storage_if hw();model 为已 build/lock 的寄存器模型,model.rg 是对应的 32 位普通 RW 寄存器;挂载与访问位于同一 initial/task 中,先声明变量:

    storage_backdoor bd = new();
    uvm_status_e status;
    uvm_reg_data_t value;
    bd.vif = hw;
    model.rg.set_backdoor(bd);
    model.rg.write(status, 'h12345678, UVM_BACKDOOR);
    if (status != UVM_IS_OK) `uvm_fatal("BACKDOOR", "Write failed")
    if (hw.value != 'h12345678) `uvm_fatal("BACKDOOR", "Hardware mismatch")
    hw.value = 'h89abcdef;
    model.rg.read(status, value, UVM_BACKDOOR);
    if (status != UVM_IS_OK || value != 'h89abcdef)
      `uvm_fatal("BACKDOOR", "Read failed")
    

    完整模型、调用方与回调计数在 backdoor_binding_probe 中。实际硬件访问替换 vif.value 的读写,并根据访问结果设置 status;此例不模拟 HDL DPI 访问失败或 W1C/RC 等副作用。

    兼容措施与范围:兼容措施不允许直接构造抽象 backdoor;使用完成实际读写的具体类,并保留所需回调链。

    迁移后验证

    具体 backdoor 挂载到寄存器后,经 RAL 后门写入并检查硬件,再改变硬件值并核对读回及镜像;检查回调次数和访问失败 status。通过 factory 创建时另验具体 override 与实际类型。

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

    已有实测与复现

    直接构造 backdoor 基类在 1.2 编译通过,在目标报 SV-ACCNBI。具体派生类在两库均通过寄存器的后门路径写入硬件 0x12345678,外部更新后读回及镜像均为 0x89abcdef;写回调和显式读回调各执行一轮,未绑定 interface 的读访问返回 UVM_NOT_OK。实验限单个 32 位 RW 寄存器、interface 存储、无 codec;不覆盖 factory override、多 codec 或实际 Verdi/DPI 集成。

    补充查阅

    扫描定位与记录结果

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

    • C25 · 启发式:直接构造目标抽象 backdoor、callback 或 socket 基类。 区分基类句柄声明和直接 new,支持先声明后赋值及嵌套类型参数;同文件按词法作用域和局部遮蔽关联,复杂路径、typedef、类外定义与预处理仍需人工核对。
    uv run tools/uvm_migration_scan.py <SoC代码目录> --rules C25
    

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

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

    源码与标准依据

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

    证据tests/uvm_review/backdoor_binding_probe.svRAL 挂载与读写;tests/uvm_review/construction_compile_probe.sv 的 REVIEW_BACKDOOR 构造断点。

    1. 继承 read 时只需在 read_func 中读数据并设 status,前后回调由 read 调用

    VCS 内置 UVM-1.2uvm_reg_backdoor.svh:353–357 依次执行 do_pre_read、read_func、do_post_read。

    VCS 内置 uvm-ieee-2020-2.0uvm_reg_backdoor.svh:278–282 保持该调用顺序;本例不在 read_func 中重复调用回调。

    补充定位

    VCS 内置 UVM-1.2uvm_reg_backdoor.svh:37class uvm_reg_backdoor)、uvm_reg_backdoor.svh:170extern virtual local task wait_for_change

    VCS 内置 uvm-ieee-2020-2.0uvm_reg_backdoor.svh:41virtual class uvm_reg_backdoor)、uvm_reg_backdoor.svh:118extern virtual task wait_for_change

    标准依据:IEEE 1800.2-2020 Annex H.2.2/H.2.3

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

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

    src/vcs-uvm-1.2/reg/uvm_reg_backdoor.svh
    // or that are not accessible using the default DPI backdoor mechanism.
    //------------------------------------------------------------------------------
    
    class uvm_reg_backdoor extends uvm_object;
    
       // Function: new
       //
       // Create an instance of this class
       //
       // Create an instance of the user-defined backdoor class
       // for the specified register or memory
       //
       function new(string name = "");
          super.new(name);
       endfunction: new
    
    
       // Task: do_pre_read
       //
    

    src/vcs-uvm-1.2/reg/uvm_reg_backdoor.svh
       // corresponding to this instance of the backdoor class will be updated
       // via a backdoor read operation.
       //
       extern virtual local task wait_for_change(uvm_object element);
    
    
       /*local*/ extern function void start_update_thread(uvm_object element);
       /*local*/ extern function void kill_update_thread(uvm_object element);
       /*local*/ extern function bit has_update_threads();
    
    
       // Task: pre_read
       //
       // Called before user-defined backdoor register read.
       //
       // The registered callback methods are invoked after the invocation
       // of this method.
       //
       virtual task pre_read(uvm_reg_item rw); endtask
    

    src/vcs-uvm-1.2/reg/uvm_reg_backdoor.svh
    // read
    
    task uvm_reg_backdoor::read(uvm_reg_item rw);
       do_pre_read(rw);
       read_func(rw);
       do_post_read(rw);
    endtask
    
    
    // read_func
    
    function void uvm_reg_backdoor::read_func(uvm_reg_item rw);
       `uvm_fatal("RegModel", "uvm_reg_backdoor::read_func() method has not been overloaded");
       rw.status = UVM_NOT_OK;
    endfunction
    
    
    `ifdef UVM_SPARSE_ARRAY
    

    完整源码 · SHA256:96182add2c5ffbd7daec3b9e2adc33c77f7141e4bfd77ff2ca26ac1579ae2d68

    src/vcs-uvm-ieee-2020-2.0/reg/uvm_reg_backdoor.svh
    //------------------------------------------------------------------------------
    
    // @uvm-ieee 1800.2-2020 auto 19.5.1
    virtual class uvm_reg_backdoor extends uvm_object;
    
    
       `uvm_object_abstract_utils(uvm_reg_backdoor)
    
    
       // @uvm-ieee 1800.2-2020 auto 19.5.2.1
       function new(string name = "");
          super.new(name);
       endfunction: new
    
    
    
       // @uvm-ieee 1800.2-2020 auto 19.5.2.2
       protected task do_pre_read(uvm_reg_item rw);
          pre_read(rw);
    

    src/vcs-uvm-ieee-2020-2.0/reg/uvm_reg_backdoor.svh
       extern virtual task wait_for_change(uvm_object element);
    
    
       /*local*/ extern function void start_update_thread(uvm_object element);
       /*local*/ extern function void kill_update_thread(uvm_object element);
       /*local*/ extern function bit has_update_threads();
    
    
    
       // @uvm-ieee 1800.2-2020 auto 19.5.2.9
       virtual task pre_read(uvm_reg_item rw); endtask
    
    
    
       // @uvm-ieee 1800.2-2020 auto 19.5.2.10
       virtual task post_read(uvm_reg_item rw); endtask
    

    src/vcs-uvm-ieee-2020-2.0/reg/uvm_reg_backdoor.svh
    // read
    
    task uvm_reg_backdoor::read(uvm_reg_item rw);
       do_pre_read(rw);
       read_func(rw);
       do_post_read(rw);
    endtask
    
    
    // read_func
    
    function void uvm_reg_backdoor::read_func(uvm_reg_item rw);
       `uvm_fatal("RegModel", "uvm_reg_backdoor::read_func() method has not been overloaded")
       rw.set_status(UVM_NOT_OK);
    endfunction
    
    
    `ifdef UVM_SPARSE_ARRAY
    

    完整源码 · SHA256:650338e20279134559f2ddcc0e250b941e1722e1e69d3edc937c637de14590df

    术语解释 · 兼容配置

    registry 延迟注册与初始化实现(M01-006) · 后门编解码可能失效(M07-023)

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

    版本适用范围