跳转至

输入查询内容

    本页内容

    字段比较、comparer、资源优先级与 FIFO 清场

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

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

    结果对比

    观察内容 UVM 1.2 UVM 2.0 UVM 2.0 + 旧 field 行为开关
    仅负向 FLAG 的 compare 结果(0=检出不匹配) negative_field_equal 0 1 0
    仅负向 FLAG 时 copy 后的字段值 negative_field_copy 123 123 123
    显式设置的类型比较开关值 explicit_comparer_check_type 0 1 1
    对象入口使用 comparer 的比较结果(1=相等) explicit_comparer_equal 1 0 0
    改用 comparer 入口后的结果(1=相等) migrated_comparer_equal 1 1 1
    show_max=0 时输出的不匹配消息数 show_max_zero_messages 0 1 1
    提高比较 verbosity 后产生的消息数 quiet_comparer_messages 0 0 0
    资源刚构造时的优先级 constructed_precedence 4321 4321 4321
    资源注册后的优先级 registered_precedence 4321 4321 4321
    构造参数中的 scope 能匹配目标路径(1=是) constructor_scope_match 1 1 1
    直接赋值后两个资源的优先级 direct_precedence_values 9999:4321 9999:4321 9999:4321
    最高优先级查询选中第一个资源(1=是) highest_is_first 1 1 1
    按名查询实际选中资源的值 direct_precedence_winner 11 22 22
    改写资源注册后的优先级 migrated_precedence 2468 2468 2468
    UVM_NO_ACTION 消息进入 catcher 的次数 no_action_catcher 1 0 0
    第一次 put:成功标志与队列项数 fifo_first_put 1:1 1:1 1:1
    第二次 put:成功标志与队列项数 fifo_second_put 1:2 1:2 1:2
    flush 向 get_ap 广播的次数 fifo_flush_broadcast 2 0 0
    flush 后 FIFO 剩余项数 fifo_flush_used 0 1 1
    显式取空后 FIFO 剩余项数 explicit_drain_used 0 0 0
    mailbox 首次读取:返回码、值、剩余数 mailbox_try_get 2:11:1 2:11:1 2:11:1
    mailbox 末次读取:返回码、值、剩余数 mailbox_try_get_last 1:22:0 1:22:0 1:22:0
    默认 packer 的位数与位流 native_pack 16:1001011001000001 28:00111010000000000000000000000000000000100000000000000000000000001111011010011000001000000000 28:00111010000000000000000000000000000000100000000000000000000000001111011010011000001000000000
    兼容 packer 的位数与位流 compat_pack 16:1001011001000001 16:1001011001000001 16:1001011001000001
    资源池默认优先级 pool_default 未记录 4321 4321
    资源池读取的资源优先级 pool_precedence 未记录 4321 4321

    运行命令

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

    uv run tools/run_uvm_review.py --case policy_probe
    

    最小源码

    policy_probe.sv

    policy_probe.sv
    `timescale 1ns/1ps
    `include "uvm_macros.svh"
    import uvm_pkg::*;
    `ifdef REVIEW_UVM20
    import uvm_compat_pkg::*;
    `endif
    
    class probe_object extends uvm_object;
      int value = 5;
      int control = 7;
      `uvm_object_utils_begin(probe_object)
        `uvm_field_int(value, UVM_NOCOPY)
        `uvm_field_int(control, UVM_ALL_ON)
      `uvm_object_utils_end
      function new(string name = "probe_object"); super.new(name); endfunction
    endclass
    
    class other_object extends uvm_object;
      `uvm_object_utils(other_object)
      function new(string name = "other_object"); super.new(name); endfunction
    endclass
    
    class quiet_object extends uvm_object;
      `uvm_object_utils(quiet_object)
      function new(string name = "quiet_object"); super.new(name); endfunction
    endclass
    
    class message_counter extends uvm_report_catcher;
      int miscompares;
      int suppressed;
      function new(); super.new("message_counter"); endfunction
      function action_e catch();
        if (get_id() == "MISCMP") miscompares++;
        if (get_id() == "NO_ACTION_PROBE") suppressed++;
        return THROW;
      endfunction
    endclass
    
    class int_sink extends uvm_component;
      `uvm_component_utils(int_sink)
      uvm_analysis_imp#(int, int_sink) imp;
      int count;
      function new(string name, uvm_component parent);
        super.new(name, parent);
        imp = new("imp", this);
      endfunction
      function void write(int value); count++; endfunction
    endclass
    
    class packed_object extends uvm_object;
      `uvm_object_utils(packed_object)
      function new(string name = "packed_object"); super.new(name); endfunction
      function void do_pack(uvm_packer packer);
        packer.pack_field_int(8'h96, 8);
        packer.pack_string("A");
      endfunction
    endclass
    
    module policy_probe;
      initial begin
        probe_object a = new("a"), b = new("b");
        quiet_object q = new("q");
        other_object o = new("o");
        message_counter catcher = new();
        uvm_comparer cmp = new();
        uvm_resource_pool pool = uvm_resource_pool::get();
        uvm_resource#(int) resource_a, resource_b, selected;
        uvm_tlm_fifo#(int) fifo = new("fifo", null, 8);
        int_sink sink = new("sink", null);
        uvm_report_object reporter = new("reporter");
        packed_object packed_value = new();
        uvm_packer packer;
        bit stream[];
        string bits_text;
        int count, before_count;
        bit same;
        mailbox#(int) mailbox_probe = new();
        int mailbox_value, mailbox_status;
        int drained_value, drained_count;
        uvm_resource_types::rsrc_q_t resources;
        uvm_resource_base winner;
    
        #1;
        uvm_report_cb::add(null, catcher);
        uvm_root::get().set_report_verbosity_level(UVM_LOW);
        b.value = 123;
        cmp.verbosity = UVM_HIGH;
        same = a.compare(b, cmp);
        $display("REVIEW|negative_field_equal|%0d", same);
        b.copy(a);
        $display("REVIEW|negative_field_copy|%0d", b.value);
    
        cmp.check_type = 0;
        same = q.compare(o, cmp);
        $display("REVIEW|explicit_comparer_check_type|%0d", cmp.check_type);
        $display("REVIEW|explicit_comparer_equal|%0d", same);
    `ifdef REVIEW_UVM20
        cmp.flush();
        cmp.set_check_type(0);
        same = cmp.compare_object("pair", q, o);
    `else
        cmp.check_type = 0;
        same = q.compare(o, cmp);
    `endif
        $display("REVIEW|migrated_comparer_equal|%0d", same);
    
        cmp.show_max = 0;
        cmp.verbosity = UVM_NONE;
        cmp.result = 0;
        before_count = catcher.miscompares;
        same = cmp.compare_field_int("field", 1, 2, 32);
        $display("REVIEW|show_max_zero_messages|%0d", catcher.miscompares - before_count);
        cmp.verbosity = UVM_HIGH;
        before_count = catcher.miscompares;
        same = cmp.compare_field_int("quiet_field", 1, 2, 32);
        $display("REVIEW|quiet_comparer_messages|%0d", catcher.miscompares - before_count);
    
        uvm_resource_base::default_precedence = 4321;
        resource_a = new("priority_probe", "env.*");
        resource_a.write(11);
        $display("REVIEW|constructed_precedence|%0d", resource_a.precedence);
        pool.set(resource_a);
        $display("REVIEW|registered_precedence|%0d", resource_a.precedence);
    `ifdef REVIEW_UVM20
        $display("REVIEW|pool_default|%0d", pool.get_default_precedence());
        $display("REVIEW|pool_precedence|%0d", pool.get_precedence(resource_a));
    `endif
        $display("REVIEW|constructor_scope_match|%0d", resource_a.match_scope("env.agent"));
        resource_b = new("priority_probe", "env.*");
        resource_b.write(22);
        pool.set(resource_b);
        resource_a.precedence = 9999;
        $display("REVIEW|direct_precedence_values|%0d:%0d", resource_a.precedence, resource_b.precedence);
        resources = pool.lookup_name("env.agent", "priority_probe", uvm_resource#(int)::get_type());
        winner = pool.get_highest_precedence(resources);
        $display("REVIEW|highest_is_first|%0d", winner == resource_a);
        selected = uvm_resource_db#(int)::get_by_name("env.agent", "priority_probe");
        $display("REVIEW|direct_precedence_winner|%0d", selected.read());
    `ifdef REVIEW_UVM20
        uvm_resource_pool::set_default_precedence(2468);
        resource_a = new("migrated_priority");
        pool.set_scope(resource_a, "env.*");
    `else
        uvm_resource_base::default_precedence = 2468;
        resource_a = new("migrated_priority", "env.*");
        resource_a.set();
    `endif
        $display("REVIEW|migrated_precedence|%0d", resource_a.precedence);
    
        reporter.set_report_id_action("NO_ACTION_PROBE", UVM_NO_ACTION);
        `uvm_info_context("NO_ACTION_PROBE", "suppressed", UVM_NONE, reporter)
        $display("REVIEW|no_action_catcher|%0d", catcher.suppressed);
    
        fifo.get_ap.connect(sink.imp);
        fifo.get_ap.resolve_bindings();
        same = fifo.try_put(11);
        $display("REVIEW|fifo_first_put|%0d:%0d", same, fifo.used());
        same = fifo.try_put(22);
        $display("REVIEW|fifo_second_put|%0d:%0d", same, fifo.used());
        fifo.flush();
        $display("REVIEW|fifo_flush_broadcast|%0d", sink.count);
        $display("REVIEW|fifo_flush_used|%0d", fifo.used());
        drained_count = 0;
        while (fifo.try_get(drained_value)) drained_count++;
        $display("REVIEW|explicit_drain_used|%0d", fifo.used());
        mailbox_probe.put(11);
        mailbox_probe.put(22);
        mailbox_status = mailbox_probe.try_get(mailbox_value);
        $display("REVIEW|mailbox_try_get|%0d:%0d:%0d", mailbox_status, mailbox_value, mailbox_probe.num());
        mailbox_status = mailbox_probe.try_get(mailbox_value);
        $display("REVIEW|mailbox_try_get_last|%0d:%0d:%0d", mailbox_status, mailbox_value, mailbox_probe.num());
    
        packer = new();
        count = packed_value.pack(stream, packer);
        bits_text = "";
        foreach (stream[i]) bits_text = {bits_text, stream[i] ? "1" : "0"};
        $display("REVIEW|native_pack|%0d:%s", count, bits_text);
    `ifdef REVIEW_UVM20
        begin
          uvm_compat_packer legacy = new();
          packer = legacy;
        end
    `endif
        count = packed_value.pack(stream, packer);
        bits_text = "";
        foreach (stream[i]) bits_text = {bits_text, stream[i] ? "1" : "0"};
        $display("REVIEW|compat_pack|%0d:%s", count, bits_text);
        $display("REVIEW|done|1");
        $finish;
      end
    endmodule
    

    全部用例 · 证据摘要

    版本适用范围