跳转至

输入查询内容

    本页内容

    具体 backdoor 挂载:RAL 读写、硬件值与回调

    环境:VCS W-2024.09-SP2-8。1.2 使用 uvm-1.2,2.0 使用 uvm-ieee-2020-2.0

    实验检查观察值是否符合预期;成功复现问题不代表问题已修复。

    结果对比

    观察内容 UVM 1.2 UVM 2.0
    寄存器挂载的是指定 backdoor(1=是) backdoor_identity 1 1
    写操作成功(1=是) write_ok 1 1
    实际硬件数据(十六进制) hardware 12345678 12345678
    读操作成功(1=是) read_ok 1 1
    读回数据(十六进制) read_value 89abcdef 89abcdef
    寄存器镜像值(十六进制) mirror 89abcdef 89abcdef
    后门写入的 pre_write:post_write 次数 write_callbacks 1:1 1:1
    显式后门读取的 pre_read:post_read 次数 read_callbacks 1:1 1:1
    未绑定 interface 的后门读返回 UVM_NOT_OK(1=是) missing_interface_rejected 1 1

    运行命令

    目录与环境准备;从解包根目录执行:

    uv run tools/run_uvm_review.py --case backdoor_binding_probe --variants 12,20
    

    最小源码

    backdoor_binding_probe.sv

    backdoor_binding_probe.sv
    `timescale 1ns/1ps
    `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
    
    class storage_reg extends uvm_reg;
      uvm_reg_field value;
      function new(string name = "storage_reg");
        super.new(name, 32, UVM_NO_COVERAGE);
      endfunction
      function void build();
        value = new("value");
        value.configure(this, 32, 0, "RW", 0, 0, 1, 0, 1);
      endfunction
    endclass
    
    class storage_block extends uvm_reg_block;
      storage_reg rg;
      function new(string name = "storage_block");
        super.new(name, UVM_NO_COVERAGE);
      endfunction
      function void build();
        rg = new(); rg.configure(this); rg.build();
        default_map = create_map("map", 0, 4, UVM_LITTLE_ENDIAN, 1);
        default_map.add_reg(rg, 0, "RW");
        lock_model();
      endfunction
    endclass
    
    class backdoor_observer extends uvm_reg_cbs;
      int before_write, after_write, before_read, after_read;
      function new(string name = "observer"); super.new(name); endfunction
      virtual task pre_write(uvm_reg_item rw); before_write++; endtask
      virtual task post_write(uvm_reg_item rw); after_write++; endtask
      virtual task pre_read(uvm_reg_item rw); before_read++; endtask
      virtual task post_read(uvm_reg_item rw); after_read++; endtask
    endclass
    
    module backdoor_binding_probe;
      storage_if hw();
      initial begin
        storage_block model = new();
        storage_backdoor bd = new();
        backdoor_observer observer = new();
        uvm_status_e status;
        uvm_reg_data_t value;
        model.build();
        bd.vif = hw;
        model.rg.set_backdoor(bd);
        uvm_callbacks#(uvm_reg_backdoor, uvm_reg_cbs)::add(bd, observer);
        $display("REVIEW|backdoor_identity|%0d", model.rg.get_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")
        $display("REVIEW|write_ok|%0d", status == UVM_IS_OK);
        $display("REVIEW|hardware|%08h", hw.value);
        // Discard observer counts for any read performed by the RAL write path.
        observer.before_read = 0; observer.after_read = 0;
        hw.value = 'h89abcdef;
        model.rg.read(status, value, UVM_BACKDOOR);
        if (status != UVM_IS_OK || value != 'h89abcdef)
          `uvm_fatal("BACKDOOR", "Read failed")
        $display("REVIEW|read_ok|%0d", status == UVM_IS_OK);
        $display("REVIEW|read_value|%08h", value[31:0]);
        $display("REVIEW|mirror|%08h", model.rg.get_mirrored_value());
        $display("REVIEW|write_callbacks|%0d:%0d", observer.before_write, observer.after_write);
        $display("REVIEW|read_callbacks|%0d:%0d", observer.before_read, observer.after_read);
        bd.vif = null;
        model.rg.read(status, value, UVM_BACKDOOR);
        $display("REVIEW|missing_interface_rejected|%0d", status == UVM_NOT_OK);
        $display("REVIEW|done|1");
        $finish;
      end
    endmodule
    

    全部用例 · 证据摘要

    版本适用范围