跳转至

输入查询内容

    本页内容

    字段操作次数、打印宏与 automation 钩子

    环境: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 行为开关
    旧打印宏传入的位宽 old_macro_size 32 117440512 117440512
    旧打印宏使用十六进制(1=是) old_macro_hex 1 0 0
    改写打印宏传入的位宽 migrated_macro_size 32 32 32
    改写打印宏使用十六进制(1=是) migrated_macro_hex 1 1 1
    仅负向 FLAG 的字段打印次数 negative_print_calls 1 0 1
    仅负向 FLAG 的字段打包位数 negative_pack_bits 32 0 32
    仅负向 FLAG 的字段记录次数 negative_record_calls 1 0 1
    旧字段操作钩子调用次数 old_automation_calls 1 0 0
    改写后的字段操作钩子调用次数 migrated_automation_calls 1 1 1

    运行命令

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

    uv run tools/run_uvm_review.py --case field_probe
    

    最小源码

    field_probe.sv

    field_probe.sv
    `timescale 1ns/1ps
    `include "uvm_macros.svh"
    import uvm_pkg::*;
    `ifdef REVIEW_UVM20
    import uvm_compat_pkg::*;
    `endif
    
    class field_packet extends uvm_object;
      int value = 96;
      `uvm_object_utils_begin(field_packet)
        `uvm_field_int(value, UVM_NOCOPY)
      `uvm_object_utils_end
      function new(string name="field_packet"); super.new(name); endfunction
    endclass
    
    class old_automation extends uvm_object;
      int calls;
      function new(string name="old_automation"); super.new(name); endfunction
      virtual function void __m_uvm_field_automation(uvm_object tmp_data__,
    `ifdef REVIEW_UVM20
                                                   uvm_field_flag_t what__,
    `else
                                                   int what__,
    `endif
                                                   string str__);
        if (what__ == UVM_COPY) calls++;
      endfunction
    endclass
    
    class migrated_automation extends uvm_object;
      int calls;
      function new(string name="migrated_automation"); super.new(name); endfunction
      virtual function void do_copy(uvm_object rhs); calls++; endfunction
    endclass
    
    class field_printer extends uvm_table_printer;
      int calls, observed_size;
      uvm_radix_enum observed_radix;
      virtual function void print_field(string name, uvm_bitstream_t value, int size,
        uvm_radix_enum radix=UVM_NORADIX, byte scope_separator=".", string type_name="");
        calls++; observed_size=size; observed_radix=radix;
      endfunction
      virtual function void print_field_int(string name, uvm_integral_t value, int size,
        uvm_radix_enum radix=UVM_NORADIX, byte scope_separator=".", string type_name="");
        calls++; observed_size=size; observed_radix=radix;
      endfunction
    endclass
    
    class field_recorder extends uvm_text_recorder;
      int calls;
      function new(string name="field_recorder"); super.new(name); endfunction
      protected virtual function void do_record_field(string name, uvm_bitstream_t value,
                                                      int size, uvm_radix_enum radix);
        if (name == "value") calls++;
      endfunction
      protected virtual function void do_record_field_int(string name, uvm_integral_t value,
                                                          int size, uvm_radix_enum radix);
        if (name == "value") calls++;
      endfunction
    endclass
    
    module field_probe;
      initial begin
        field_packet packet = new();
        field_printer printer = new();
        field_recorder recorder = new();
        uvm_text_tr_database db = new("db");
        uvm_tr_stream tr_stream;
        old_automation old_a = new(), old_b = new();
        migrated_automation new_a = new(), new_b = new();
    `ifdef REVIEW_UVM20
        uvm_compat_packer packer = new();
    `else
        uvm_packer packer = new();
    `endif
        bit bits[];
        int count, value = 96;
        #1;
        uvm_default_printer = printer;
        `uvm_print_int(value, UVM_HEX)
        $display("REVIEW|old_macro_size|%0d", printer.observed_size);
        $display("REVIEW|old_macro_hex|%0d", printer.observed_radix == UVM_HEX);
    `ifdef REVIEW_UVM20
        `uvm_print_int(value, $bits(value), UVM_HEX)
    `else
        `uvm_print_int(value, UVM_HEX)
    `endif
        $display("REVIEW|migrated_macro_size|%0d", printer.observed_size);
        $display("REVIEW|migrated_macro_hex|%0d", printer.observed_radix == UVM_HEX);
        printer.calls=0;
        void'(packet.sprint(printer));
        $display("REVIEW|negative_print_calls|%0d", printer.calls);
        count = packet.pack(bits, packer);
        $display("REVIEW|negative_pack_bits|%0d", count);
        tr_stream = db.open_stream("stream", "scope", "type");
        recorder.m_do_open(tr_stream, 0, "type");
        packet.record(recorder);
        $display("REVIEW|negative_record_calls|%0d", recorder.calls);
        recorder.close();
        old_a.copy(old_b);
        new_a.copy(new_b);
        $display("REVIEW|old_automation_calls|%0d", old_a.calls);
        $display("REVIEW|migrated_automation_calls|%0d", new_a.calls);
        $display("REVIEW|done|1");
        $finish;
      end
    endmodule
    

    全部用例 · 证据摘要

    版本适用范围