Java教程

日常记录(69)回顾/100

本文主要是介绍日常记录(69)回顾/100,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

uvm的功能覆盖率收集

类定义

创建了一个类,继承于uvm_subscriber#(trans_name)
https://gitee.com/bai-mengwei/sy_uvm_tb/blob/main/inout_coverage.sv#L4
另外需要定义和实例化trans后,后面write的时候需要赋值。

实现write函数

用于外部调用,名字必须为t。(继承关系)

        function void write(packet t);
            pkt_cg.sa = t.sa;
            pkt_cg.da = t.da;
            inout_addr.sample();
        endfunction: write

提取和报告

        function void extract_phase(uvm_phase phase);
            cov = inout_addr.get_coverage();
        endfunction: extract_phase

        function void report_phase(uvm_phase phase);
            `uvm_info("COVERAGE_INFO", $sformatf("coverage value is %f", cov), UVM_LOW);
        endfunction: report_phase

参数化类注册到factory

正常使用的注册方法,参数化类使用:uvm_component_param_utils

module taa ();
    import uvm_pkg::*;
    class TestA #(int WIDTH=32) extends uvm_component;
        // data or class properties
        `uvm_component_param_utils(TestA)
        /* `uvm_component_utils(TestA) */
        rand bit [WIDTH:0] a;

        function new(string name="11", uvm_component parent);
            super.new(name, parent);
        endfunction: new
    endclass : TestA

    initial begin
        /* TestA#(16) a = new("11"); */
        TestA a;
        a = TestA#(32)::type_id::create("11", uvm_top);
        a.a = 1;
        $display("factory ok");
        uvm_top.print();
        $finish;
    end
endmodule

输出结果:

factory ok
-------------------------------------
Name       Type           Size  Value
-------------------------------------
<unnamed>  uvm_root       -     @171 
  11       uvm_component  -     @335 
-------------------------------------
$finish called from file "taa.sv", line 21.
$finish at simulation time                    0

如果不使用,而是和其它一样使用的uvm_component_utils,则:输出类型是本身定义的类型。

factory ok
--------------------------------
Name       Type      Size  Value
--------------------------------
<unnamed>  uvm_root  -     @171 
  11       TestA     -     @335 
--------------------------------
$finish called from file "taa.sv", line 21.
$finish at simulation time                    0

SV的构造函数继承

没有定义构造函数

自动继承上一层:

module tbb ();
    class Base;
        int a;
        function new();
            $display("show a ");
        endfunction : new

    endclass : Base

    class B extends Base;
        int b;
    endclass : B

    initial begin
        B b = new();
    end
endmodule

输出:

show a 

SV中的clone方法等

clone方法是等价于new和copy的,需要$cast强制转换(不一定转换成功,如果不对)。
A本身是继承了uvm_object的,如果不注册到工厂中,直接可以使用new,带入string,但是继承到工厂中,则需要重新实现一下new构造函数。
这样才能使用。

module tcc ();
    import uvm_pkg::*;
    class A extends uvm_object;
        // data or class properties
        int a;
        `uvm_object_utils_begin(A)
        `uvm_field_int(a, UVM_ALL_ON)
        `uvm_object_utils_end

        // initialization
        function new(string name="A");
            super.new("A");
        endfunction : new

    endclass : A

    class C extends A;
        // data or class properties
        `uvm_object_utils(C)

        function new(string name="C");
        endfunction : new

    endclass : C 

    initial begin
        A a = new("aa");
        A b;
        C c = new("cc");

        /* c = a; */
        a = c;
        a.a = 1;

        /* b = a.clone(); */
        $cast(b, a.clone());
        $display("value in b %d ", b.a);
        $display("value in c %d ", c.a);
    end
endmodule

输出结果:

value in b           1 
value in c           1 

子父类、名称函数

uvm_root是顶层类,uvm全局实例化一个uvm_top的实例化类。

  • get_type_name 通用函数,打印出实例化的类名
  • get_parent,uvm_top没有parent,为null,下面定义的tb是有parent的。
  • m_parent变量,在component中的内部直接可用变量,为父类实例。
  • 此外还有get_child、get_children、get_first_child、等函数。
module tdd ();
    import uvm_pkg::*;
    class test_base extends uvm_test;
        `uvm_component_utils(test_base)
        // data or class properties

        // initialization
        function new(string name="test_base", uvm_component parent);
            super.new(name, parent);
        endfunction : new

    endclass : test_base

    initial begin
        test_base tb = new("tb", uvm_top);
        uvm_top.print();
        $display("uvm_root name: ", uvm_root::get());
        $display("--------------------------------");
        $display("uvm_top name: ", uvm_top.get_type_name());
        $display("--------------------------------");
        $display("uvm_top parent : ", uvm_top.get_parent());
        $display("--------------------------------");
        $display("test_case parent : ", tb.get_parent());
        $display("--------------------------------");
        $display("test_case parent name: ", tb.get_parent().get_type_name());
        $display("--------------------------------");
        $display("test_case parent name: ", tb.m_parent.get_type_name());
        ;
    end
endmodule

输出结果:

---------------------------------
Name       Type       Size  Value
---------------------------------
<unnamed>  uvm_root   -     @171 
  tb       test_base  -     @335 
---------------------------------
uvm_root name: '{use_uvm_seeding:'h1, m_leaf_name:"", m_inst_id:171, m_inst_count:344, __m_uvm_status_container:{ ref to class uvm_status_container}, uvm_global_copy_map:'{}, m_rh:{ ref to class uvm_report_handler}, enable_stop_interrupt:0, m_config_deprecated_warned:'h0, m_config_set:'h1, print_config_matches:'h0, print_enabled:'h1, tr_database:null, m_domain:{ ref to class uvm_domain}, m_phase_imps:'{}, m_current_phase:null, m_phase_process:null, m_build_done:'h0, m_phasing_active:0, m_parent:null, m_children:'{"tb":{ ref to class uvm_component}} , m_children_by_handle:'{ref to class test_base:{ ref to class uvm_component}} , m_main_stream:null, m_streams:'{}, m_tr_h:'{}, m_name:"", type_name:"uvm_component", event_pool:null, recording_detail:'h0, m_verbosity_settings:'{}, m_time_settings:'{}, m_uvm_applied_cl_action:'{}, m_uvm_applied_cl_sev:'{}, clp:{ ref to class uvm_cmdline_processor}, finish_on_completion:'h1, top_levels:'{{ ref to class uvm_component}} , enable_print_topology:'h0, phase_timeout:9200, m_inst:{ ref to class uvm_root}, m_phase_all_done:'h0, trace_args:'{}, clp_inst:{ ref to class uvm_cmdline_processor}, disable_apply_cfg_settings:'h0, m_relnotes_done:'h1}
--------------------------------
uvm_top name: uvm_root
--------------------------------
uvm_top parent : null
--------------------------------
test_case parent : '{use_uvm_seeding:'h1, m_leaf_name:"", m_inst_id:171, m_inst_count:344, __m_uvm_status_container:{ ref to class uvm_status_container}, uvm_global_copy_map:'{}, m_rh:{ ref to class uvm_report_handler}, enable_stop_interrupt:0, m_config_deprecated_warned:'h0, m_config_set:'h1, print_config_matches:'h0, print_enabled:'h1, tr_database:null, m_domain:{ ref to class uvm_domain}, m_phase_imps:'{}, m_current_phase:null, m_phase_process:null, m_build_done:'h0, m_phasing_active:0, m_parent:null, m_children:'{"tb":{ ref to class uvm_component}} , m_children_by_handle:'{ref to class test_base:{ ref to class uvm_component}} , m_main_stream:null, m_streams:'{}, m_tr_h:'{}, m_name:"", type_name:"uvm_component", event_pool:null, recording_detail:'h0, m_verbosity_settings:'{}, m_time_settings:'{}, m_uvm_applied_cl_action:'{}, m_uvm_applied_cl_sev:'{}, clp:{ ref to class uvm_cmdline_processor}, finish_on_completion:'h1, top_levels:'{{ ref to class uvm_component}} , enable_print_topology:'h0, phase_timeout:9200, m_inst:{ ref to class uvm_root}, m_phase_all_done:'h0, trace_args:'{}, clp_inst:{ ref to class uvm_cmdline_processor}, disable_apply_cfg_settings:'h0, m_relnotes_done:'h1}
--------------------------------
test_case parent name: uvm_root
--------------------------------
test_case parent name: uvm_root

automation中嵌入if

if语句不可能在class中的function或者task之外的,但是在automation中间是可以的。

module tee ();
    import uvm_pkg::*;
    class packet extends uvm_sequence_item;
        rand bit a;
        rand int b;
        `uvm_object_utils_begin(packet)
        `uvm_field_int(a, UVM_ALL_ON)
        if (a) begin
            `uvm_field_int(b, UVM_ALL_ON)
        end

        `uvm_object_utils_end
        // data or class properties

        // initialization
        function new(string name="packet");
            super.new(name);
        endfunction : new

    endclass : packet

    initial begin
        packet pt;
        pt = new("pt");
        pt.randomize() with{a==1;};
        pt.print();
        pt.randomize() with{a==0;};
        pt.print();

    end
endmodule

正常输出:

--------------------------------
Name  Type      Size  Value     
--------------------------------
pt    packet    -     @335      
  a   integral  1     'h1       
  b   integral  32    'he91ad7b9
--------------------------------
---------------------------
Name  Type      Size  Value
---------------------------
pt    packet    -     @335 
  a   integral  1     'h0  
---------------------------

打印信息、行为控制

重载严重性

set_report_severity_override

设置最大ERROR退出

set_report_max_quit_count

设置自定义的严重性的行为

set_report_severity_action

设置严重性文件

set_report_severity_file

$stop和自动ERROR停止的有效性

使用run等ucli命令,实现继续运行
https://blog.csdn.net/kevindas/article/details/78991759

module tff ();
    import uvm_pkg::*;
    class info_test extends uvm_component;
        UVM_FILE error_log;
        `uvm_component_utils(info_test)
        // data or class properties
        function void info_print();
            `uvm_info("UVM_INFO1", "UVM_INFO1", UVM_LOW);
            `uvm_info("UVM_INFO1", "UVM_INFO1", UVM_LOW);
            `uvm_info("UVM_INFO1", "UVM_INFO1", UVM_LOW);
            `uvm_info("UVM_INFO1", "UVM_INFO1", UVM_LOW);
            `uvm_warning("UVM_WARNING", "UVM_WARNING");
            `uvm_warning("UVM_WARNING", "UVM_WARNING");
            `uvm_warning("UVM_WARNING", "UVM_WARNING");
            `uvm_warning("UVM_WARNING", "UVM_WARNING");
        endfunction: info_print

        // initialization
        function new(string name="info_test", uvm_component parent);
            super.new(name, parent);
        endfunction : new

        function void set_severity();
            error_log = $fopen("error.log", "w");
            set_report_severity_override(UVM_INFO, UVM_WARNING);
            set_report_severity_override(UVM_WARNING, UVM_ERROR);
            // don't have effect
            /* set_report_severity_id_override(UVM_INFO, "info_test", UVM_WARNING); */
            set_report_max_quit_count(3);
            set_report_severity_action(UVM_ERROR, UVM_STOP | UVM_DISPLAY | UVM_COUNT | UVM_LOG);
            set_report_severity_file(UVM_ERROR, error_log);
            $stop;
            $error("fake: now the max quit count is %d", 3);// get_report_max_quit_count());

        endfunction: set_severity

        function void final_phase(uvm_phase phase);
            // can't reach, there is no run_test call
            super.final_phase(phase);
            $display("final");
            $fclose(error_log);
        endfunction: final_phase

    endclass : info_test

    initial begin
        info_test it;
        it = info_test::type_id::create("info_test", uvm_top);
        it.set_severity();
        it.info_print();
    end
endmodule

输出结果:
$stop不影响结果UVM的ERROR计数

$stop at time 0 Scope: tff.\info_test::set_severity  File: tff.sv Line: 32
ucli% run
Error: "tff.sv", 33: tff: at time 0
fake: now the max quit count is           3
UVM_WARNING tff.sv(8) @ 0: info_test [UVM_INFO1] UVM_INFO1
UVM_WARNING tff.sv(9) @ 0: info_test [UVM_INFO1] UVM_INFO1
UVM_WARNING tff.sv(10) @ 0: info_test [UVM_INFO1] UVM_INFO1
UVM_WARNING tff.sv(11) @ 0: info_test [UVM_INFO1] UVM_INFO1
UVM_ERROR tff.sv(12) @ 0: info_test [UVM_WARNING] UVM_WARNING
ucli% run
UVM_ERROR tff.sv(13) @ 0: info_test [UVM_WARNING] UVM_WARNING
ucli% run
UVM_ERROR tff.sv(14) @ 0: info_test [UVM_WARNING] UVM_WARNING
UVM_INFO /home/synopsys/vcs-mx/O-2018.09-1/etc/uvm-1.2/base/uvm_report_server.svh(894) @ 0: reporter [UVM/REPORT/SERVER] 
--- UVM Report Summary ---

Quit count reached!
Quit count :     3 of     3
** Report counts by severity
UVM_INFO :    1
UVM_WARNING :    4
UVM_ERROR :    3
UVM_FATAL :    0
** Report counts by id
[UVM/RELNOTES]     1
[UVM_INFO1]     4
[UVM_WARNING]     3

$finish called from file "/home/synopsys/vcs-mx/O-2018.09-1/etc/uvm-1.2/base/uvm_root.svh", line 135.
$finish at simulation time                    0

层次结构与检查赋值

打印层次结构

下面二者大同小异,

  • uvm_top.print();
  • uvm_top.print_topology();
  • factory是只有在uvm-1.1 才可以使用的。显示进入工工厂的类名了。
module tgg ();
    import uvm_pkg::*;
    
    class my_env extends uvm_env;
        `uvm_component_utils(my_env)
        // data or class properties
        int a;

        // initialization
        function new(string name="my_env", uvm_component parent);
            super.new(name, parent);
        endfunction : new

        function void build_phase(uvm_phase phase);
            super.build_phase(phase);
            uvm_config_db#(int)::get(this, "", "int_value", a);
            `uvm_info("VALUE_A", $sformatf("value a is %d", a), UVM_LOW)
        endfunction: build_phase

    endclass : my_env
    class base_test extends uvm_test;
        my_env env;
        `uvm_component_utils(base_test)
        // data or class properties

        function void build_phase(uvm_phase phase);
            super.build_phase(phase);
            env = my_env::type_id::create("env_path", this);
            /* uvm_config_db#(int)::set(this, "env_path", "int_value", 1); */
            uvm_config_db#(bit [3:0])::set(this, "env_path", "int_value", 1);
        endfunction: build_phase

        // initialization
        function new(string name="base_test", uvm_component parent);
            super.new(name, parent);
        endfunction : new

        function void start_of_simulation_phase(uvm_phase phase);
            super.start_of_simulation_phase(phase);
            uvm_top.print();
            uvm_top.print_topology();
            check_config_usage();
            // only used in uvm1.1
            /* factory.print(); */
        endfunction: start_of_simulation_phase
    endclass : base_test

    initial begin
        run_test("base_test");
    end
endmodule

检查赋值是否正常

check_config_usage。
以下是异常的,因为uvm_config_db没有给定正确的类型名。
输出结果:

UVM_INFO @ 0: reporter [RNTST] Running test base_test...
UVM_INFO tgg.sv(17) @ 0: uvm_test_top.env_path [VALUE_A] value a is           0
--------------------------------------
Name            Type       Size  Value
--------------------------------------
<unnamed>       uvm_root   -     @172 
  uvm_test_top  base_test  -     @336 
    env_path    my_env     -     @349 
--------------------------------------
UVM_INFO /home/synopsys/vcs-mx/O-2018.09-1/etc/uvm-1.2/base/uvm_root.svh(589) @ 0: reporter [UVMTOP] UVM testbench topology:
------------------------------------
Name          Type       Size  Value
------------------------------------
uvm_test_top  base_test  -     @336 
  env_path    my_env     -     @349 
------------------------------------

UVM_INFO @ 0: uvm_test_top [CFGNRD]  ::: The following resources have at least one write and no reads :::
 int_value [/^uvm_test_top\.env_path$/] : (bit[3:0]) 1   
UVM_INFO /home/synopsys/vcs-mx/O-2018.09-1/etc/uvm-1.2/base/uvm_resource.svh(564) @ 0: reporter [UVM/RESOURCE/ACCESSOR] uvm_test_top reads: 0 @ 0  writes: 1 @ 0

UVM_INFO /home/synopsys/vcs-mx/O-2018.09-1/etc/uvm-1.2/base/uvm_report_server.svh(894) @ 0: reporter [UVM/REPORT/SERVER] 
--- UVM Report Summary ---

** Report counts by severity
UVM_INFO :    6
UVM_WARNING :    0
UVM_ERROR :    0
UVM_FATAL :    0
** Report counts by id
[CFGNRD]     1
[RNTST]     1
[UVM/RELNOTES]     1
[UVM/RESOURCE/ACCESSOR]     1
[UVMTOP]     1
[VALUE_A]     1

$finish called from file "/home/synopsys/vcs-mx/O-2018.09-1/etc/uvm-1.2/base/uvm_root.svh", line 527.
$finish at simulation time                    0

UVM-1.2不再使用default_sequence机制

UVM—1.1进行drv和seq通信时:

module tgg ();
    import uvm_pkg::*;
    class my_trans extends uvm_sequence_item;
        `uvm_object_utils(my_trans)
        rand int a;

        function new(string name="my_trans");
            super.new(name);
        endfunction : new
    endclass : my_trans

    class my_drv extends uvm_driver#(my_trans);
        `uvm_component_utils(my_drv)

        function new(string name="drv", uvm_component parent);
            super.new(name, parent);
        endfunction : new

        task run_phase(uvm_phase phase);
            forever begin
                seq_item_port.get_next_item(req);
                `uvm_info("MY_DRV", $sformatf("get an item %d", req.a), UVM_LOW)
                seq_item_port.get_next_item(req);
                `uvm_info("MY_DRV", $sformatf("get an item %d", req.a), UVM_LOW)
                seq_item_port.item_done();
            end
        endtask: run_phase
    endclass : my_drv

    class my_seq extends uvm_sequence#(my_trans);
        `uvm_object_utils(my_seq)

        function new(string name="my_seq");
            super.new(name);
        endfunction: new

        task body();
            /* starting_phase.raise_objection(this); */
            if (starting_phase!=null) begin
                starting_phase.raise_objection(this);
            end
            /* repeat (10) begin */
            /*     `uvm_do_with(req, {a>0; a < 10;}) */ 
            /*     `uvm_info("SEQ_SEND", "send seq", UVM_LOW) */
            /* end */
            req = new("my_trans");
            for (int i = 0; i < 10; i++) begin
                start_item(req);
                req.randomize() with {a>5; a< 10;};
                finish_item(req);
            end
            if (starting_phase!=null) begin
                starting_phase.drop_objection(this);
            end
        endtask
    endclass : my_seq

    class my_test extends uvm_test;
        `uvm_component_utils(my_test);
        typedef uvm_sequencer#(my_trans) my_seqr;
        my_drv drv;
        my_seqr seqr;

        function new(string name="tes", uvm_component parent);
            super.new(name, parent);
        endfunction : new

        function void build_phase(uvm_phase phase);
            super.build_phase(phase);
            seqr = my_seqr::type_id::create("seqr", this);
            drv = my_drv::type_id::create("drv", this);
            uvm_config_db#(uvm_object_wrapper)::set(this, "seqr.main_phase", "default_sequence", my_seq::type_id::get());
        endfunction: build_phase

        function void connect_phase(uvm_phase phase);
            super.connect_phase(phase);
            drv.seq_item_port.connect(seqr.seq_item_export);
        endfunction: connect_phase

    endclass : my_test

    initial begin
        run_test("my_test");
    end
endmodule

uvm_config_db#(uvm_object_wrapper)::set(this, "seqr.main_phase", "default_sequence", my_seq::type_id::get());
输出正常。

点击查看代码
UVM_INFO @ 0: reporter [RNTST] Running test my_test...
UVM_INFO tff.sv(22) @ 0: uvm_test_top.drv [MY_DRV] get an item           7
UVM_ERROR @ 0: uvm_test_top.seqr [uvm_test_top.seqr] Get_next_item called twice without item_done or get in between
UVM_INFO tff.sv(24) @ 0: uvm_test_top.drv [MY_DRV] get an item           7
UVM_INFO tff.sv(22) @ 0: uvm_test_top.drv [MY_DRV] get an item           9
UVM_ERROR @ 0: uvm_test_top.seqr [uvm_test_top.seqr] Get_next_item called twice without item_done or get in between
UVM_INFO tff.sv(24) @ 0: uvm_test_top.drv [MY_DRV] get an item           9
UVM_INFO tff.sv(22) @ 0: uvm_test_top.drv [MY_DRV] get an item           7
UVM_ERROR @ 0: uvm_test_top.seqr [uvm_test_top.seqr] Get_next_item called twice without item_done or get in between
UVM_INFO tff.sv(24) @ 0: uvm_test_top.drv [MY_DRV] get an item           7
UVM_INFO tff.sv(22) @ 0: uvm_test_top.drv [MY_DRV] get an item           6
UVM_ERROR @ 0: uvm_test_top.seqr [uvm_test_top.seqr] Get_next_item called twice without item_done or get in between
UVM_INFO tff.sv(24) @ 0: uvm_test_top.drv [MY_DRV] get an item           6
UVM_INFO tff.sv(22) @ 0: uvm_test_top.drv [MY_DRV] get an item           6
UVM_ERROR @ 0: uvm_test_top.seqr [uvm_test_top.seqr] Get_next_item called twice without item_done or get in between
UVM_INFO tff.sv(24) @ 0: uvm_test_top.drv [MY_DRV] get an item           6
UVM_INFO tff.sv(22) @ 0: uvm_test_top.drv [MY_DRV] get an item           9
UVM_ERROR @ 0: uvm_test_top.seqr [uvm_test_top.seqr] Get_next_item called twice without item_done or get in between
UVM_INFO tff.sv(24) @ 0: uvm_test_top.drv [MY_DRV] get an item           9
UVM_INFO tff.sv(22) @ 0: uvm_test_top.drv [MY_DRV] get an item           8
UVM_ERROR @ 0: uvm_test_top.seqr [uvm_test_top.seqr] Get_next_item called twice without item_done or get in between
UVM_INFO tff.sv(24) @ 0: uvm_test_top.drv [MY_DRV] get an item           8
UVM_INFO tff.sv(22) @ 0: uvm_test_top.drv [MY_DRV] get an item           7
UVM_ERROR @ 0: uvm_test_top.seqr [uvm_test_top.seqr] Get_next_item called twice without item_done or get in between
UVM_INFO tff.sv(24) @ 0: uvm_test_top.drv [MY_DRV] get an item           7
UVM_INFO tff.sv(22) @ 0: uvm_test_top.drv [MY_DRV] get an item           6
UVM_ERROR @ 0: uvm_test_top.seqr [uvm_test_top.seqr] Get_next_item called twice without item_done or get in between
UVM_INFO tff.sv(24) @ 0: uvm_test_top.drv [MY_DRV] get an item           6
UVM_INFO tff.sv(22) @ 0: uvm_test_top.drv [MY_DRV] get an item           9
UVM_ERROR @ 0: uvm_test_top.seqr [uvm_test_top.seqr] Get_next_item called twice without item_done or get in between
UVM_INFO tff.sv(24) @ 0: uvm_test_top.drv [MY_DRV] get an item           9

--- UVM Report Summary ---

** Report counts by severity
UVM_INFO :   21
UVM_WARNING :    0
UVM_ERROR :   10
UVM_FATAL :    0
** Report counts by id
[MY_DRV]    20
[RNTST]     1
[uvm_test_top.seqr]    10
$finish called from file "/home/synopsys/vcs-mx/O-2018.09-1/etc/uvm-1.1/base/uvm_root.svh", line 439.
$finish at simulation time                    0

但是使用uvm-1.2则异常:

点击查看代码
UVM_INFO @ 0: reporter [RNTST] Running test my_test...
UVM_INFO tff.sv(22) @ 0: uvm_test_top.drv [MY_DRV] get an item           7
UVM_ERROR @ 0: uvm_test_top.seqr [uvm_test_top.seqr] Get_next_item called twice without item_done or get in between
UVM_INFO tff.sv(24) @ 0: uvm_test_top.drv [MY_DRV] get an item           7
UVM_INFO tff.sv(22) @ 0: uvm_test_top.drv [MY_DRV] get an item           9
UVM_ERROR @ 0: uvm_test_top.seqr [uvm_test_top.seqr] Get_next_item called twice without item_done or get in between
UVM_INFO tff.sv(24) @ 0: uvm_test_top.drv [MY_DRV] get an item           9
UVM_INFO /home/synopsys/vcs-mx/O-2018.09-1/etc/uvm-1.2/base/uvm_report_server.svh(894) @ 0: reporter [UVM/REPORT/SERVER] 
--- UVM Report Summary ---

** Report counts by severity
UVM_INFO :    6
UVM_WARNING :    0
UVM_ERROR :    2
UVM_FATAL :    0
** Report counts by id
[MY_DRV]     4
[RNTST]     1
[UVM/RELNOTES]     1
[uvm_test_top.seqr]     2

$finish called from file "/home/synopsys/vcs-mx/O-2018.09-1/etc/uvm-1.2/base/uvm_root.svh", line 527.
$finish at simulation time                    0

UVM—1.1进行drv和seq通信时:

取消使用starting_phase机制,而是在其它地方,手动实例化seq,然后指定seqr,发送。
实例:

module tgg ();
    import uvm_pkg::*;
    class my_trans extends uvm_sequence_item;
        `uvm_object_utils(my_trans)
        rand int a;

        function new(string name="my_trans");
            super.new(name);
        endfunction : new
    endclass : my_trans

    class my_drv extends uvm_driver#(my_trans);
        `uvm_component_utils(my_drv)
        static int i=0;

        function new(string name="drv", uvm_component parent);
            super.new(name, parent);
        endfunction : new

        task run_phase(uvm_phase phase);
            /* forever begin */
            /*     seq_item_port.get_next_item(req); */
            /*     `uvm_info("MY_DRV", $sformatf("i: %0d, get an item %d", i, req.a), UVM_LOW) */
            /*     seq_item_port.get_next_item(req); */
            /*     `uvm_info("MY_DRV", $sformatf("i: %0d, get an item %d", i, req.a), UVM_LOW) */
            /*     seq_item_port.item_done(); */
            /*     i = i + 1; */
            /* end */
            forever begin
                seq_item_port.try_next_item(req);
                if(req!=null) begin
                    `uvm_info("MY_DRV", $sformatf("i: %0d, get an item %d", i, req.a), UVM_LOW)
                    i++;
                    seq_item_port.item_done();
                end else begin
                    ;
                end
            end
        endtask: run_phase
    endclass : my_drv

    class my_seq extends uvm_sequence#(my_trans);
        `uvm_object_utils(my_seq)

        function new(string name="my_seq");
            super.new(name);
        endfunction: new

        task body();
            repeat (5) begin
                `uvm_do_with(req, {a>0; a < 10;}) 
                `uvm_info("SEQ_SEND", "send seq", UVM_LOW)
            end
            req = new("my_trans");
            for (int i = 0; i < 5; i++) begin
                start_item(req);
                req.randomize() with {a>5; a< 10;};
                finish_item(req);
            end
        endtask
    endclass : my_seq

    class my_test extends uvm_test;
        `uvm_component_utils(my_test);
        typedef uvm_sequencer#(my_trans) my_seqr;
        my_drv drv;
        my_seqr seqr;
        my_seq seq;

        function new(string name="tes", uvm_component parent);
            super.new(name, parent);
        endfunction : new

        function void build_phase(uvm_phase phase);
            super.build_phase(phase);
            seqr = my_seqr::type_id::create("seqr", this);
            drv = my_drv::type_id::create("drv", this);
            /* uvm_config_db#(uvm_object_wrapper)::set(this, "seqr.main_phase", "default_sequence", seq.get_type()); */
        endfunction: build_phase

        function void connect_phase(uvm_phase phase);
            super.connect_phase(phase);
            drv.seq_item_port.connect(seqr.seq_item_export);
        endfunction: connect_phase

        task run_phase(uvm_phase phase);
            super.run_phase(phase);
            phase.raise_objection(this);
            seq = new("seq");
            seq.start(seqr);
            phase.drop_objection(this);
        endtask: run_phase
    endclass : my_test

    initial begin
        run_test("my_test");
    end
endmodule

输出结果:

UVM_INFO @ 0: reporter [RNTST] Running test my_test...
UVM_INFO tgg.sv(32) @ 0: uvm_test_top.drv [MY_DRV] i: 0, get an item           9
UVM_INFO tgg.sv(52) @ 0: uvm_test_top.seqr@@seq [SEQ_SEND] send seq
UVM_INFO tgg.sv(32) @ 0: uvm_test_top.drv [MY_DRV] i: 1, get an item           2
UVM_INFO tgg.sv(52) @ 0: uvm_test_top.seqr@@seq [SEQ_SEND] send seq
UVM_INFO tgg.sv(32) @ 0: uvm_test_top.drv [MY_DRV] i: 2, get an item           1
UVM_INFO tgg.sv(52) @ 0: uvm_test_top.seqr@@seq [SEQ_SEND] send seq
UVM_INFO tgg.sv(32) @ 0: uvm_test_top.drv [MY_DRV] i: 3, get an item           6
UVM_INFO tgg.sv(52) @ 0: uvm_test_top.seqr@@seq [SEQ_SEND] send seq
UVM_INFO tgg.sv(32) @ 0: uvm_test_top.drv [MY_DRV] i: 4, get an item           4
UVM_INFO tgg.sv(52) @ 0: uvm_test_top.seqr@@seq [SEQ_SEND] send seq
UVM_INFO tgg.sv(32) @ 0: uvm_test_top.drv [MY_DRV] i: 5, get an item           7
UVM_INFO tgg.sv(32) @ 0: uvm_test_top.drv [MY_DRV] i: 6, get an item           7
UVM_INFO tgg.sv(32) @ 0: uvm_test_top.drv [MY_DRV] i: 7, get an item           8
UVM_INFO tgg.sv(32) @ 0: uvm_test_top.drv [MY_DRV] i: 8, get an item           9
UVM_INFO tgg.sv(32) @ 0: uvm_test_top.drv [MY_DRV] i: 9, get an item           7
UVM_INFO /home/synopsys/vcs-mx/O-2018.09-1/etc/uvm-1.2/base/uvm_objection.svh(1276) @ 0: reporter [TEST_DONE] 'run' phase is ready to proceed to the 'extract' phase
UVM_INFO /home/synopsys/vcs-mx/O-2018.09-1/etc/uvm-1.2/base/uvm_report_server.svh(894) @ 0: reporter [UVM/REPORT/SERVER] 
--- UVM Report Summary ---

** Report counts by severity
UVM_INFO :   18
UVM_WARNING :    0
UVM_ERROR :    0
UVM_FATAL :    0
** Report counts by id
[MY_DRV]    10
[RNTST]     1
[SEQ_SEND]     5
[TEST_DONE]     1
[UVM/RELNOTES]     1

$finish called from file "/home/synopsys/vcs-mx/O-2018.09-1/etc/uvm-1.2/base/uvm_root.svh", line 527.
$finish at simulation time                    0

seqr\seq\drv通信机制

  • drv是get方式向seqr要数据的。seq要发的话,要seqr同意,seqr是看drv要不要的。
  • drv在get到数据后,如果认定这个数据没有收到,那重新get,seqr是备份了seq的数据的,可以再次给drv。
  • drv在get到数据后,收到了,发送item_done,seqr知道drv得到数据了,就删掉了备份。
  • seq发送的时候,使用宏uvm_do[_with],可以使用:实例化、start_item、然后randomize、然后finish_item的形式进行发送。
这篇关于日常记录(69)回顾/100的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!