1. 程式人生 > 其它 >日常記錄(68)常規-40

日常記錄(68)常規-40

urandom_range

  • 只有一個引數,是從0到該引數的範圍。
  • 有兩個引數,大小無所謂,但是範圍是二者之間幷包括二者。
module taa ();
    initial begin
        for (int i = 0; i < 100; i++) begin
            #1;
            $display("random value:", $urandom_range(1));
        end
    end
endmodule

冗餘度控制

外部配置的+UVM_VERBOSITY如果更高,但是內部控制的冗餘度更低,那麼最終顯示是更低的效果。

set_report_verbosity_level

控制當前的冗餘度,字尾hier表示一個向下繼承。

set_report_id_verbosity

字尾的level去掉,然後report變為report_id,這樣控制當前元件的某一個id的顯示冗餘度,能夠跨越對整個冗餘度。
字尾hier表示向下繼承。

+UVM_VERBOSITY=NONE

其中NONE是UVM_NONE,這裡的UVM_可以省去。

uvm_object的冗餘度

內部沒有設定冗餘度函式函式,使用上層繼承。

module tbb ();
    import uvm_pkg::*;
    class info_obj extends uvm_object;

        task run_phase(uvm_phase phase);
            `uvm_info("INFO_ID1", "UVM_HIGH", UVM_HIGH);
            `uvm_info("INFO_ID2", "UVM_MEDIUM", UVM_MEDIUM);
            `uvm_info("INFO_ID3", "UVM_LOW", UVM_LOW);
            `uvm_info("INFO_ID4", "UVM_NONE", UVM_NONE);
            `uvm_warning("INFO_ID5", "WARNING");
        endtask: run_phase

    endclass : info_obj

    class info_comp extends uvm_component;
        // data or class properties
        function new(string name="info_comp", uvm_component parent);
            super.new(name, parent);
        endfunction: new

        task run_phase(uvm_phase phase);
            `uvm_info("INFO_ID1", "UVM_HIGH", UVM_HIGH);
            `uvm_info("INFO_ID2", "UVM_MEDIUM", UVM_MEDIUM);
            `uvm_info("INFO_ID3", "UVM_LOW", UVM_LOW);
            `uvm_info("INFO_ID4", "UVM_NONE", UVM_NONE);
            `uvm_warning("INFO_ID5", "WARNING");
        endtask: run_phase

        function void set_level();
            set_report_id_verbosity("INFO_ID3", UVM_NONE);
        endfunction: set_level

    endclass : info_comp

    initial begin
        info_obj obj = new();
        info_comp comp = new("info_comp", null);

        /* uvm_top.set_report_verbosity_level_hier(UVM_NONE); */
        /* uvm_top.set_report_id_verbosity_hier("INFO_ID3", UVM_NONE); */ 
        uvm_top.set_report_id_verbosity_hier("INFO_ID3", UVM_NONE); 
        obj.run_phase(null);

        comp.set_level();
        comp.run_phase(null);
    end
endmodule

輸出結果:

UVM_INFO tbb.sv(7) @ 0: reporter [INFO_ID2] UVM_MEDIUM
UVM_INFO tbb.sv(9) @ 0: reporter [INFO_ID4] UVM_NONE
UVM_WARNING tbb.sv(10) @ 0: reporter [INFO_ID5] WARNING
UVM_INFO tbb.sv(23) @ 0: info_comp [INFO_ID2] UVM_MEDIUM
UVM_INFO tbb.sv(25) @ 0: info_comp [INFO_ID4] UVM_NONE
UVM_WARNING tbb.sv(26) @ 0: info_comp [INFO_ID5] WARNING

random的回撥

pre_randomize、post_randomize

回撥函式,randomize前後自動執行。

module tcc ();
    class random_test;
        // data or class properties
        rand bit [3:0] sa;
        randc bit [3:0] da;

        function void pre_randomize();
            $display("before random: %0b, %0b", sa, da);
        endfunction: pre_randomize

        function void post_randomize();
            $display("after random: %0b, %0b", sa ,da);
        endfunction: post_randomize
    endclass : random_test

    initial begin
        random_test rt = new();
        for (int i = 0; i < 10; i++) begin
            rt.randomize();
            #1;
        end
        $display("the end.");
    end
endmodule

輸出結果:

點選檢視程式碼
before random: 0, 0
after random: 11, 101
before random: 11, 101
after random: 110, 1
before random: 110, 1
after random: 1, 10
before random: 1, 10
after random: 1001, 11
before random: 1001, 11
after random: 1101, 100
before random: 1101, 100
after random: 111, 0
before random: 111, 0
after random: 0, 111
before random: 0, 111
after random: 10, 1001
before random: 10, 1001
after random: 1101, 110
before random: 1101, 110
after random: 1010, 1110
the end.

automation測試

pack、unpack、print、compare

pack過程中,使用pack_bytes函式,傳入的動態陣列,打包得到的4個byte資料在que中,然後通過%p、顯示了一下。
unpack_bytes函式,傳入了一個佇列,然後將資料恢復到了pt2中了。

module tdd ();
    import uvm_pkg::*;
    class print_test extends uvm_object;
        // data or class properties
        int a;

        `uvm_object_utils_begin(print_test)
        `uvm_field_int(a, UVM_ALL_ON)
        `uvm_object_utils_end

        // initialization
        function new(string name="print_test");
            super.new(name);
            a = 1;
        endfunction : new

    endclass : print_test

    initial begin
        print_test pt = new ("pt");
        print_test pt2 = new ("pt2");
        byte unsigned que[];

        uvm_active_passive_enum is_active;
        pt.print();
        pt2.a = 1;
        $display("value compare ans: %d", pt.compare(pt2));

        pt.a = 3;
        $display("pack size : %d ", pt.pack_bytes(que));
        $display("pack bytes : %p", que);
        pt2.unpack_bytes(que);
        $display("after unpack on pt2");
        pt2.print();
        /* pt.un */
        $display("default value %s", UVM_ACTIVE);
        $display("active value %d, %s", UVM_ACTIVE, UVM_ACTIVE);

    end
endmodule

輸出結果:

-----------------------------
Name  Type        Size  Value
-----------------------------
pt    print_test  -     @335 
  a   integral    32    'h1  
-----------------------------
value compare ans: 1
pack size :          32 
pack bytes : '{'h0, 'h0, 'h0, 'h3} 
after unpack on pt2
-----------------------------
Name  Type        Size  Value
-----------------------------
pt2   print_test  -     @336 
  a   integral    32    'h3  
-----------------------------
default value UVM_ACTIVE
active value 1, UVM_ACTIVE

TLM通訊

combine\comm_test\comm_send

  • combine進行了一些連線,
  • cs通過write廣播資料。而ct接收資料的時候,使用廣播接收資料,同時使用阻塞接收資料
  • 阻塞接收資料使用uvm_tlm_analysis_fifo的形式。

連線通路

uvm_analysis_port - uvm_analysis_imp
uvm_analysis_port - uvm_tlm_analysis_fifo.analysis_export - uvm_tlm_analysis_fifo.blocking_get_export - uvm_blocking_get_port

使用方法

  • function void write(int a);
  • uvm_blocking_get_port.get(a);
module tee ();
    import uvm_pkg::*;
    class comm_test extends uvm_component; 
        // data or class properties
        uvm_analysis_imp #(int, comm_test) ap;
        uvm_tlm_analysis_fifo #(int) taf;
        uvm_blocking_get_port #(int) bgp;

        // initialization
        function new(string name="comm_test", uvm_component parent);
            super.new(name, parent);
            ap = new("ap", this);
            bgp = new("bgp", this);
            taf = new("taf", this);
        endfunction : new

        function void connect_phase(uvm_phase phase);
            super.connect_phase(phase);
            /* bgp.connect(taf.blocking_get_export); */
            /* taf.blocking_get_export.connect(bgi); */
        endfunction: connect_phase

        function void write(int a);
            $display("get a value a %d", a);
        endfunction: write

        task run_phase(uvm_phase phase);
            int a;
            $display("before value a from fifo %d", a);
            bgp.get(a);
            $display("value a from fifo %d", a);
        endtask: run_phase

    endclass : comm_test

    class comm_send extends uvm_component;
        // data or class properties
        uvm_analysis_port#(int) ap;

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

        task run_phase(uvm_phase phase);
            ap.write(1);
            `uvm_info("SEND_FLAG", "SEND FINISHED.",  UVM_LOW)
        endtask: run_phase
    endclass : comm_send

    class combine extends uvm_test;
        // data or class properties
        `uvm_component_utils(combine)
        comm_test ct;
        comm_send cs;

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

        function void build_phase(uvm_phase phase);
            super.build_phase(phase);
            ct=new("ct", this);
            cs=new("cs", this);
        endfunction: build_phase

        function void connect_phase(uvm_phase phase);
            super.connect_phase(phase);
            cs.ap.connect(ct.ap);
            cs.ap.connect(ct.taf.analysis_export);
            ct.bgp.connect(ct.taf.blocking_get_export);
        endfunction: connect_phase

    endclass : combine

    initial begin
        run_test("combine");
    end
endmodule

輸出結果:

UVM_INFO @ 0: reporter [RNTST] Running test combine...
get a value a           1
UVM_INFO tee.sv(48) @ 0: uvm_test_top.cs [SEND_FLAG] SEND FINISHED.
before value a from fifo           0
value a from fifo           1
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 :    3
UVM_WARNING :    0
UVM_ERROR :    0
UVM_FATAL :    0
** Report counts by id
[RNTST]     1
[SEND_FLAG]     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



Le vent se lève! . . . il faut tenter de vivre!

Le vent se lève! . . . il faut tenter de vivre!