跳转至

输入查询内容

    本页内容

    手册改写示例:动作宏、factory、event 与策略接口

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

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

    结果对比

    观察内容 UVM 1.2 UVM 2.0
    reset 前保存的数据句柄仍可使用 event_saved_data 1 1
    独立输出前清理 printer,连续两次输出有效 printer_reuse 1 1
    自定义 report server 格式方法保留默认文本并添加前缀 server_format 1 1
    已覆盖的旧动作宏映射数 macro_mappings 15 15
    检查上下文和优先级的实际传输次数 macro_transfers 16 16
    发送前后保留已有对象身份的检查次数 macro_existing_identity 6 6
    同一委托工厂的注册查询、类型别名与实例别名检查通过 factory_delegate 未记录 1
    目标 packer 状态接口往返保留 16 位数据 packer_state_roundtrip 未记录 1
    目标 event 使用显式默认数据 event_explicit_default 未记录 1

    运行命令

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

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

    最小源码

    manual_actions_probe.sv

    manual_actions_probe.sv
    `timescale 1ns/1ps
    `include "uvm_macros.svh"
    import uvm_pkg::*;
    
    class action_item extends uvm_sequence_item;
      `uvm_object_utils(action_item)
      rand int value;
      function new(string name="action_item"); super.new(name); endfunction
    endclass
    class action_derived_item extends action_item;
      `uvm_object_utils(action_derived_item)
      function new(string name="action_derived_item"); super.new(name); endfunction
    endclass
    class action_seqr extends uvm_sequencer#(action_item);
      int last_priority;
      function new(string name, uvm_component parent); super.new(name,parent); endfunction
      virtual task wait_for_grant(uvm_sequence_base sequence_ptr,
                                 int item_priority=-1, bit lock_request=0);
        last_priority=item_priority;
        super.wait_for_grant(sequence_ptr,item_priority,lock_request);
      endtask
    endclass
    class consumer_link;
      action_seqr consumer_seqr;
    endclass
    class action_sequence extends uvm_sequence#(action_item);
      action_seqr target_seqr;
      consumer_link cons_if=new();
      int expected_value, expected_priority;
      bit check_value;
      action_seqr expected_seqr;
      action_item saved;
      int identity_checks;
      function new(string name="action_sequence"); super.new(name); endfunction
      function void expect_transfer(action_seqr sqr, int priority_value, bit constrained);
        expected_seqr=sqr;
        expected_priority=priority_value;
        check_value=constrained;
        expected_value=42;
      endfunction
      task body();
        action_seqr local_seqr;
        if (!$cast(local_seqr, get_sequencer())) $fatal(1,"sequencer type");
        cons_if.consumer_seqr=target_seqr;
        expect_transfer(local_seqr, 100, 0);
    `ifdef REVIEW_UVM20
        `uvm_do(req)
    `else
        `uvm_do(req)
    `endif
        expect_transfer(local_seqr, 37, 0);
    `ifdef REVIEW_UVM20
        `uvm_do(req, get_sequencer(), 37)
    `else
        `uvm_do_pri(req, 37)
    `endif
        expect_transfer(local_seqr, 100, 1);
    `ifdef REVIEW_UVM20
        `uvm_do(req, get_sequencer(), -1, {value==42;})
    `else
        `uvm_do_with(req, {value==42;})
    `endif
        expect_transfer(local_seqr, 37, 1);
    `ifdef REVIEW_UVM20
        `uvm_do(req, get_sequencer(), 37, {value==42;})
    `else
        `uvm_do_pri_with(req, 37, {value==42;})
    `endif
        expect_transfer(target_seqr, 100, 0);
    `ifdef REVIEW_UVM20
        `uvm_do(req, target_seqr)
    `else
        `uvm_do_on(req, target_seqr)
    `endif
        expect_transfer(target_seqr, 37, 0);
    `ifdef REVIEW_UVM20
        `uvm_do(req, target_seqr, 37)
    `else
        `uvm_do_on_pri(req, target_seqr, 37)
    `endif
        expect_transfer(target_seqr, 100, 1);
    `ifdef REVIEW_UVM20
        `uvm_do(req, target_seqr, -1, {value==42;})
    `else
        `uvm_do_on_with(req, target_seqr, {value==42;})
    `endif
        expect_transfer(target_seqr, 37, 1);
    `ifdef REVIEW_UVM20
        `uvm_do(req, target_seqr, 37, {value==42;})
    `else
        `uvm_do_on_pri_with(req, target_seqr, 37, {value==42;})
    `endif
        expect_transfer(target_seqr, 100, 0);
    `ifdef REVIEW_UVM20
        `uvm_do(req, cons_if.consumer_seqr)
    `else
        `uvm_do_seq(req, cons_if)
    `endif
        expect_transfer(target_seqr, 100, 1);
    `ifdef REVIEW_UVM20
        `uvm_do(req, cons_if.consumer_seqr, -1, {value==42;})
    `else
        `uvm_do_seq_with(req, cons_if, {value==42;})
    `endif
    `ifdef REVIEW_UVM20
        `uvm_create(req, target_seqr)
    `else
        `uvm_create_on(req, target_seqr)
    `endif
        saved=req; req.value=42; expect_transfer(target_seqr, 100, 1);
    `ifdef REVIEW_UVM20
        `uvm_send(req)
    `else
        `uvm_send(req)
    `endif
        if (req!=saved) $fatal(1,"send recreated object");
        identity_checks++;
    `ifdef REVIEW_UVM20
        `uvm_create(req, cons_if.consumer_seqr)
    `else
        `uvm_create_seq(req, cons_if)
    `endif
        saved=req; req.value=42; expect_transfer(target_seqr, 37, 1);
    `ifdef REVIEW_UVM20
        `uvm_send(req, 37)
    `else
        `uvm_send_pri(req, 37)
    `endif
        if (req!=saved) $fatal(1,"send recreated object");
        identity_checks++;
    `ifdef REVIEW_UVM20
        `uvm_create(req, target_seqr)
    `else
        `uvm_create_on(req, target_seqr)
    `endif
        saved=req; req.value=42; expect_transfer(target_seqr, 100, 0);
    `ifdef REVIEW_UVM20
        `uvm_rand_send(req)
    `else
        `uvm_rand_send(req)
    `endif
        if (req!=saved) $fatal(1,"send recreated object");
        identity_checks++;
    `ifdef REVIEW_UVM20
        `uvm_create(req, cons_if.consumer_seqr)
    `else
        `uvm_create_seq(req, cons_if)
    `endif
        saved=req; req.value=42; expect_transfer(target_seqr, 37, 0);
    `ifdef REVIEW_UVM20
        `uvm_rand_send(req, 37)
    `else
        `uvm_rand_send_pri(req, 37)
    `endif
        if (req!=saved) $fatal(1,"send recreated object");
        identity_checks++;
    `ifdef REVIEW_UVM20
        `uvm_create(req, target_seqr)
    `else
        `uvm_create_on(req, target_seqr)
    `endif
        saved=req; req.value=42; expect_transfer(target_seqr, 100, 1);
    `ifdef REVIEW_UVM20
        `uvm_rand_send(req, -1, {value==42;})
    `else
        `uvm_rand_send_with(req, {value==42;})
    `endif
        if (req!=saved) $fatal(1,"send recreated object");
        identity_checks++;
    `ifdef REVIEW_UVM20
        `uvm_create(req, cons_if.consumer_seqr)
    `else
        `uvm_create_seq(req, cons_if)
    `endif
        saved=req; req.value=42; expect_transfer(target_seqr, 37, 1);
    `ifdef REVIEW_UVM20
        `uvm_rand_send(req, 37, {value==42;})
    `else
        `uvm_rand_send_pri_with(req, 37, {value==42;})
    `endif
        if (req!=saved) $fatal(1,"send recreated object");
        identity_checks++;
      endtask
    endclass
    
    `ifdef REVIEW_UVM20
    class action_factory extends uvm_factory;
      uvm_default_factory delegate = new();
      virtual function void register(uvm_object_wrapper obj); delegate.register(obj); endfunction
      virtual function void set_inst_override_by_type(uvm_object_wrapper original_type, uvm_object_wrapper override_type, string full_inst_path);
        delegate.set_inst_override_by_type(original_type, override_type, full_inst_path);
      endfunction
      virtual function void set_inst_override_by_name(string original_type_name, string override_type_name, string full_inst_path);
        delegate.set_inst_override_by_name(original_type_name, override_type_name, full_inst_path);
      endfunction
      virtual function void set_type_override_by_type(uvm_object_wrapper original_type, uvm_object_wrapper override_type, bit replace=1);
        delegate.set_type_override_by_type(original_type, override_type, replace);
      endfunction
      virtual function void set_type_override_by_name(string original_type_name, string override_type_name, bit replace=1);
        delegate.set_type_override_by_name(original_type_name, override_type_name, replace);
      endfunction
      virtual function uvm_object create_object_by_type(uvm_object_wrapper requested_type, string parent_inst_path="", string name="");
        return delegate.create_object_by_type(requested_type, parent_inst_path, name);
      endfunction
      virtual function uvm_component create_component_by_type(uvm_object_wrapper requested_type, string parent_inst_path="", string name, uvm_component parent);
        return delegate.create_component_by_type(requested_type, parent_inst_path, name, parent);
      endfunction
      virtual function uvm_object create_object_by_name(string requested_type_name, string parent_inst_path="", string name="");
        return delegate.create_object_by_name(requested_type_name, parent_inst_path, name);
      endfunction
      virtual function uvm_component create_component_by_name(string requested_type_name, string parent_inst_path="", string name, uvm_component parent);
        return delegate.create_component_by_name(requested_type_name, parent_inst_path, name, parent);
      endfunction
      virtual function void debug_create_by_type(uvm_object_wrapper requested_type, string parent_inst_path="", string name="");
        delegate.debug_create_by_type(requested_type, parent_inst_path, name);
      endfunction
      virtual function void debug_create_by_name(string requested_type_name, string parent_inst_path="", string name="");
        delegate.debug_create_by_name(requested_type_name, parent_inst_path, name);
      endfunction
      virtual function uvm_object_wrapper find_override_by_type(uvm_object_wrapper requested_type, string full_inst_path);
        return delegate.find_override_by_type(requested_type, full_inst_path);
      endfunction
      virtual function uvm_object_wrapper find_override_by_name(string requested_type_name, string full_inst_path);
        return delegate.find_override_by_name(requested_type_name, full_inst_path);
      endfunction
      virtual function uvm_object_wrapper find_wrapper_by_name(string type_name);
        return delegate.find_wrapper_by_name(type_name);
      endfunction
      virtual function void print(int all_types=1); delegate.print(all_types); endfunction
    virtual function bit is_type_name_registered(string type_name);
      return delegate.is_type_name_registered(type_name);
    endfunction
    virtual function bit is_type_registered(uvm_object_wrapper obj);
      return delegate.is_type_registered(obj);
    endfunction
    virtual function void set_type_alias(string alias_type_name,
                                         uvm_object_wrapper original_type);
      delegate.set_type_alias(alias_type_name, original_type);
    endfunction
    virtual function void set_inst_alias(string alias_type_name,
                                         uvm_object_wrapper original_type,
                                         string full_inst_path);
      delegate.set_inst_alias(alias_type_name, original_type, full_inst_path);
    endfunction
    endclass
    `endif
    class action_server extends uvm_default_report_server;
    virtual function string compose_report_message(
        uvm_report_message report_message, string report_object_name = "");
      return {"[team] ",
              super.compose_report_message(report_message, report_object_name)};
    endfunction
    endclass
    
    module manual_actions_probe;
      int transfers=0;
      action_sequence seq;
      task automatic consume(action_seqr sqr);
        action_item received;
        forever begin
          sqr.get_next_item(received);
          if (sqr!=seq.expected_seqr || received.get_sequencer()!=sqr ||
              received.get_parent_sequence()!=seq) $fatal(1,"request context mismatch");
          if (sqr.last_priority!=seq.expected_priority) $fatal(1,"priority mismatch");
          if (seq.check_value && received.value!=seq.expected_value) $fatal(1,"value mismatch");
          transfers++;
          sqr.item_done();
        end
      endtask
      initial begin
        action_seqr local_seqr=new("local_seqr",null), target_seqr=new("target_seqr",null);
        uvm_event ev=new("ev");
        action_item item=new("item"), saved_item;
        uvm_object saved_data;
        uvm_table_printer printer=new();
        string text;
        action_server server=new();
        uvm_report_message msg=uvm_report_message::new_report_message();
    `ifdef REVIEW_UVM20
        action_factory factory_value=new();
        uvm_object obj;
        action_derived_item derived;
        uvm_packer p=new(), restored=new();
        bit unsigned state[];
        factory_value.register(action_item::get_type());
        factory_value.register(action_derived_item::get_type());
        if (!factory_value.is_type_registered(action_item::get_type()) ||
            !factory_value.is_type_name_registered("action_item") ||
            factory_value.is_type_name_registered("missing")) $fatal(1,"registration queries");
        factory_value.set_type_alias("item_alias",action_item::get_type());
        factory_value.set_inst_alias("scoped_alias",action_item::get_type(),"scope.item");
        factory_value.set_type_override_by_type(action_item::get_type(),action_derived_item::get_type());
        obj=factory_value.create_object_by_name("item_alias","scope","plain");
        if (!$cast(derived,obj)) $fatal(1,"type alias override");
        obj=factory_value.create_object_by_name("scoped_alias","scope","item");
        if (!$cast(derived,obj)) $fatal(1,"instance alias override");
        $display("REVIEW|factory_delegate|1");
        p.flush(); p.pack_field_int('h1234,16); p.get_packed_bits(state);
        restored.set_packed_bits(state);
        if (restored.unpack_field_int(16)!='h1234) $fatal(1,"packer state roundtrip");
        $display("REVIEW|packer_state_roundtrip|1");
    `endif
        item.value=42;
        ev.trigger(item);
        saved_data=ev.get_trigger_data();
        if (!$cast(saved_item,saved_data)) $fatal(1,"event data type");
        ev.reset();
        if (saved_item!=item || saved_item.value!=42) $fatal(1,"event snapshot");
        $display("REVIEW|event_saved_data|1");
    `ifdef REVIEW_UVM20
        if (ev.get_trigger_data()!=null) $fatal(1,"event reset default");
        ev.set_default_data(item); ev.trigger(); ev.reset();
        if (ev.get_trigger_data()!=item) $fatal(1,"event explicit default");
        $display("REVIEW|event_explicit_default|1");
    `endif
        repeat(2) begin
    `ifdef REVIEW_UVM20
          printer.flush();
    `endif
          printer.print_field("value",32'h1234,32,UVM_HEX);
          text=printer.emit();
          if (text=="") $fatal(1,"empty printer output");
        end
        $display("REVIEW|printer_reuse|1");
        msg.set_id("ACTION"); msg.set_message("hello");
        text=server.compose_report_message(msg,"probe");
        if (text.substr(0,6)!="[team] ") $fatal(1,"custom server format");
        $display("REVIEW|server_format|1");
        seq=new(); seq.target_seqr=target_seqr;
        fork
          consume(local_seqr);
          consume(target_seqr);
        join_none
        seq.start(local_seqr);
        disable fork;
        if (transfers!=16 || seq.identity_checks!=6) $fatal(1,"macro coverage");
        $display("REVIEW|macro_mappings|15");
        $display("REVIEW|macro_transfers|%0d",transfers);
        $display("REVIEW|macro_existing_identity|%0d",seq.identity_checks);
        $display("REVIEW|done|1");
        $finish;
      end
      initial begin #100; $fatal(1,"manual action timeout"); end
    endmodule
    

    全部用例 · 证据摘要

    版本适用范围