跳转至

输入查询内容

    本页内容

    接口签名、配置与寄存器访问权限

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

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

    结果对比

    观察内容 UVM 1.2 UVM 2.0
    对象 type_name 不带括号的读取结果 object_bare_type_name interface_object interface_object
    registry 的 type_name 不带括号读取结果 registry_bare_type_name interface_object interface_object
    组件 type_name 不带括号的读取结果 component_bare_type_name uvm_agent uvm_agent
    event 的类型名 event_type_name uvm_event uvm_pkg::uvm_event#(T)
    pool 的类型名 pool_type_name uvm_pool uvm_pool
    queue 的类型名 queue_type_name uvm_queue uvm_queue
    event 回调调用次数 event_callback_calls 1 1
    verbosity 的 warning 被观察到的次数 high_warning_seen 0 1
    降级 warning 被观察到的次数 demoted_warning_seen 0 1
    直接调用报告接口时 catcher 收到的消息数 direct_no_action_seen 1 1
    自动配置后的已注册字段值 automatic_field 42 42
    未注册字段的实际值 unregistered_field 0 0
    带非空 context 的正则配置查询结果 relative_regex 0:0 1:51
    无复位字段对应资源的查询结果 automatic_reset_resource 1 0
    W1C 字段在只读 map 下的有效权限 access_W1C RO:NOACCESS RO:W1C
    WRC 字段在只读 map 下的有效权限 access_WRC RC:NOACCESS RC:WO
    W1SRC 字段在只读 map 下的有效权限 access_W1SRC RC:NOACCESS RC:W1S
    W0SRC 字段在只读 map 下的有效权限 access_W0SRC RC:NOACCESS RC:W0S
    W1CRS 字段在只读 map 下的有效权限 access_W1CRS RS:NOACCESS RS:W1C
    W0CRS 字段在只读 map 下的有效权限 access_W0CRS RS:NOACCESS RS:W0C
    WCRS 字段在只读 map 下的有效权限 access_WCRS RS:NOACCESS RS:WC
    WSRC 字段在只读 map 下的有效权限 access_WSRC RC:NOACCESS RC:WS
    WO 字段在只读 map 下的有效权限 access_WO NOACCESS:WO NOACCESS:WO
    kill 阻塞读取后 can_get 返回值(1=可取) fifo_after_kill_can_get 0 1
    kill 阻塞读取后 FIFO 剩余项数 fifo_after_kill_used 1 1

    运行命令

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

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

    最小源码

    interface_probe.sv

    interface_probe.sv
    `timescale 1ns/1ps
    `include "uvm_macros.svh"
    import uvm_pkg::*;
    
    class interface_object extends uvm_object;
      `uvm_object_utils(interface_object)
      function new(string name="interface_object"); super.new(name); endfunction
    endclass
    
    class event_counter extends uvm_event_callback;
      int calls;
      function new(); super.new("event_counter"); endfunction
      virtual function void post_trigger(uvm_event e, uvm_object data); calls++; endfunction
    endclass
    
    class interface_catcher extends uvm_report_catcher;
      int seen[string];
      function new(); super.new("interface_catcher"); endfunction
      function action_e catch();
        if (get_id() inside {"HIGH_WARNING", "DEMOTED_WARNING", "DIRECT_NO_ACTION"}) begin
          seen[get_id()]++;
          return CAUGHT;
        end
        return THROW;
      endfunction
    endclass
    
    class automatic_component extends uvm_component;
      int value;
      `uvm_component_utils_begin(automatic_component)
        `uvm_field_int(value, UVM_ALL_ON)
      `uvm_component_utils_end
      function new(string name, uvm_component parent); super.new(name, parent); endfunction
    `ifdef REVIEW_UVM20
      virtual function bit use_automatic_config(); return !$test$plusargs("DISABLE_AUTO_CONFIG"); endfunction
    `endif
    endclass
    
    class hidden_component extends uvm_component;
      `uvm_component_utils(hidden_component)
      int value;
      function new(string name, uvm_component parent); super.new(name, parent); endfunction
    endclass
    
    class interface_register extends uvm_reg;
      function new(string name="register"); super.new(name, 32, UVM_NO_COVERAGE); endfunction
    endclass
    
    class interface_block extends uvm_reg_block;
      function new(); super.new("block", UVM_NO_COVERAGE); endfunction
    endclass
    
    module interface_probe;
      initial begin
        event_counter callback = new();
        uvm_event ev = new("ev");
        interface_catcher catcher = new();
        uvm_report_object reporter = new("reporter");
        uvm_pool#(string,int) pool = new();
        uvm_queue#(int) queue_value = new();
        uvm_tlm_fifo#(int) fifo = new("fifo", null, 8);
        automatic_component automatic_value = new("automatic_value", null);
        hidden_component hidden_value = new("hidden_value", null);
        interface_block model = new();
        interface_register register_value = new();
        uvm_reg_field field_value = new("field");
        uvm_reg_map read_map, write_map;
        uvm_resource#(bit) reset_resource;
        uvm_phase run_node;
        process blocked;
        int value, regex_value;
        bit ok;
        string modes[] = '{"W1C", "WRC", "W1SRC", "W0SRC", "W1CRS", "W0CRS", "WCRS", "WSRC", "WO"};
    
        #1;
        $display("REVIEW|object_bare_type_name|%s", interface_object::type_name);
        $display("REVIEW|registry_bare_type_name|%s", interface_object::type_id::type_name);
        $display("REVIEW|component_bare_type_name|%s", uvm_agent::type_name);
        $display("REVIEW|event_type_name|%s", ev.get_type_name());
        $display("REVIEW|pool_type_name|%s", pool.get_type_name());
        $display("REVIEW|queue_type_name|%s", queue_value.get_type_name());
    `ifdef REVIEW_UVM20
        uvm_callbacks#(uvm_event, uvm_event_callback)::add(ev, callback);
    `else
        ev.add_callback(callback);
    `endif
        ev.trigger();
    `ifdef REVIEW_UVM20
        uvm_callbacks#(uvm_event, uvm_event_callback)::delete(ev, callback);
    `else
        ev.delete_callback(callback);
    `endif
        ev.trigger();
        $display("REVIEW|event_callback_calls|%0d", callback.calls);
    
        uvm_report_cb::add(reporter, catcher);
        reporter.set_report_verbosity_level(UVM_NONE);
        reporter.uvm_report_warning("HIGH_WARNING", "explicit verbosity", UVM_HIGH);
        reporter.set_report_severity_id_override(UVM_WARNING, "DEMOTED_WARNING", UVM_INFO);
        reporter.uvm_report_warning("DEMOTED_WARNING", "demoted verbosity", UVM_HIGH);
        reporter.set_report_id_action("DIRECT_NO_ACTION", UVM_NO_ACTION);
        reporter.uvm_report_warning("DIRECT_NO_ACTION", "direct call", UVM_NONE);
        $display("REVIEW|high_warning_seen|%0d", catcher.seen["HIGH_WARNING"]);
        $display("REVIEW|demoted_warning_seen|%0d", catcher.seen["DEMOTED_WARNING"]);
        $display("REVIEW|direct_no_action_seen|%0d", catcher.seen["DIRECT_NO_ACTION"]);
    
        uvm_config_db#(int)::set(null, "automatic_value", "value", 42);
        uvm_config_db#(int)::set(null, "hidden_value", "value", 42);
        automatic_value.build_phase(null);
        hidden_value.build_phase(null);
        $display("REVIEW|automatic_field|%0d", automatic_value.value);
        $display("REVIEW|unregistered_field|%0d", hidden_value.value);
        uvm_config_db#(int)::set(automatic_value, "/agent(0|1)/", "regex", 51);
        ok = uvm_config_db#(int)::get(null, "automatic_value.agent1", "regex", regex_value);
        $display("REVIEW|relative_regex|%0d:%0d", ok, regex_value);
    
        register_value.configure(model);
        field_value.configure(register_value, 32, 0, "RW", 0, 0, 0, 1, 1);
        read_map = model.create_map("read_map", 0, 4, UVM_LITTLE_ENDIAN);
        write_map = model.create_map("write_map", 0, 4, UVM_LITTLE_ENDIAN);
        read_map.add_reg(register_value, 0, "RO");
        write_map.add_reg(register_value, 0, "WO");
        model.lock_model();
        reset_resource = uvm_resource_db#(bit)::get_by_name({"REG::", field_value.get_full_name()}, "NO_REG_HW_RESET_TEST", 0);
        $display("REVIEW|automatic_reset_resource|%0d", reset_resource != null);
        foreach (modes[i]) begin
          void'(field_value.set_access(modes[i]));
          $display("REVIEW|access_%s|%s:%s", modes[i], field_value.get_access(read_map), field_value.get_access(write_map));
        end
    
        fork
          begin
            blocked = process::self();
            fifo.get(value);
          end
        join_none
        #1;
        blocked.kill();
        ok = fifo.try_put(19);
        $display("REVIEW|fifo_after_kill_can_get|%0d", fifo.can_get());
        $display("REVIEW|fifo_after_kill_used|%0d", fifo.used());
        $display("REVIEW|done|1");
        $finish;
      end
    endmodule
    

    全部用例 · 证据摘要

    版本适用范围