日常记录(62)域、phase、TLM

域的自动化

copy

copy 方法的结果如下代码:
首先是注册,注意copy方法的调用者是被赋值的对象,参数是来源的对象。
do_copy是在copy后自动执行的方法,是一个回调函数。

点击查看代码
module taa ();
    import uvm_pkg::*;
    `include "uvm_macros.svh"
    class box extends uvm_object;
        // data or class properties
        int length=10;
        typedef enum bit[3:0] {
            BLACK,
            WHITE,
            RED,
            BLUE
        } color_t;
        color_t color=BLUE;
        int width=5;
        string name="box_base";
        `uvm_object_utils_begin(box)
        `uvm_field_int(length, UVM_ALL_ON)
        `uvm_field_int(width, UVM_ALL_ON)
        `uvm_field_enum(color_t, color, UVM_ALL_ON)
        `uvm_object_utils_end

        function void do_copy(uvm_object rhs);
            length = 100;
        endfunction: do_copy
        // initialization
        function new();
        endfunction : new
    endclass : box

    initial begin
        box box1 = new();
        box box2 = new();
        box1.length = 5;
        box1.width = 3;
        box2.copy(box1);
        box1.print();
        box2.print();
    end
endmodule

点击查看代码
--------------------------------
Name       Type      Size  Value
--------------------------------
<unnamed>  box       -     @455 
  length   integral  32    'h5  
  width    integral  32    'h3  
  color    color_t   4     BLUE 
--------------------------------
--------------------------------
Name       Type      Size  Value
--------------------------------
<unnamed>  box       -     @456 
  length   integral  32    'h64 
  width    integral  32    'h3  
  color    color_t   4     BLUE 
--------------------------------

compare

基本原理同copy,但是以下代码自定义了uvm_comparer,然后在compare的过程中将其传入,可修改显示的不匹配个数控制。

点击查看代码
module taa ();
    import uvm_pkg::*;
    `include "uvm_macros.svh"
    class box extends uvm_object;
        // data or class properties
        int length=10;
        typedef enum bit[3:0] {
            BLACK,
            WHITE,
            RED,
            BLUE
        } color_t;
        color_t color=BLUE;
        int width=5;
        string name="box_base";
        `uvm_object_utils_begin(box)
        `uvm_field_int(length, UVM_ALL_ON)
        `uvm_field_int(width, UVM_ALL_ON)
        `uvm_field_enum(color_t, color, UVM_ALL_ON)
        `uvm_object_utils_end

    endclass : box

    initial begin
        box box1 = new();
        box box2 = new();
        uvm_comparer cmpr = new();
        cmpr.show_max = 2;
        box1.length = 'h5;
        box1.width = 'h3;
        box2.length = 'h51;
        box2.width = 'h11;
        if(box2.compare(box1, cmpr)) begin
            $info("same");
        end else begin
            $info("not same");
        end
    end
endmodule
点击查看代码
UVM_INFO @ 0: reporter [MISCMP] Miscompare for <object>.length: lhs = 'h51 : rhs = 'h5
UVM_INFO @ 0: reporter [MISCMP] Miscompare for <object>.width: lhs = 'h11 : rhs = 'h3
UVM_INFO @ 0: reporter [MISCMP] 2 Miscompare(s) for object @455 vs. @456
Info: "taa.sv", 36: taa: at time 0
not same

print

在调用print的过程中,使用uvm_default_printer,默认为table的形式,可以将其它的printer赋值到uvm_default_printer,实现打印格式控制。

uvm_default_printer
uvm_default_line_printer
uvm_default_tree_printer

此外,同uvm_comparer一样,可以定义uvm_table_printer等,修改其中的knobs.full_name,调用print时候传入,完成打印过程控制。

phase概念

image

内部概念

schedule是包括phase的关联数组
domain内置一个schedule
schedule所属类uvm_schedule和domain所属类uvm_domain都是继承于uvm_phase

编写规范

由于未来可能对run_phase中的reset、configure、main、shutdown的废除,建议使用run_phase,并使用fork-join语句块实现同步。

OVM的历史遗留变量传递

传递方法

不同于uvm的set_config_db,ovm使用set_config_int、set_config_string、get_config_int、get_config_string等方法

隐式get

可能不用get函数也可获得set过的数据。
但是依赖于具体的field_automation、然后需要调用suoer.build_phase,即可匹配同名,自动获取值。

实例代码

以下代码实现了ovm的数值传递。

  • string类型的数据没有注册到automation,是手动set和get的
  • int的val1类型是注册到automation,然后通过调用父类自动get的,因此前后都是100
  • int的val3类型是注册到automation,但是值和字符串的域不一样,无法赋值,只能通过手动方式获取值
    另外,如果get_config_int改成了get_config_string,类型不一致不会报错,但是无法获得值。
点击查看代码
module set_config_variable;
    import uvm_pkg::*;
    `include "uvm_macros.svh"

    class comp1 extends uvm_component; 
        int val1 = 1;
        string str1 = "null";
        int val2 = 123;
        `uvm_component_utils_begin(comp1)
        `uvm_field_int(val1, UVM_ALL_ON)
        `uvm_field_int(val2, UVM_ALL_ON)
        `uvm_component_utils_end
        function new(string name, uvm_component parent);
            super.new(name, parent);
        endfunction
        function void build_phase(uvm_phase phase);
            super.build_phase(phase);
            `uvm_info("SETVAL", $sformatf("val1 is %d before get", val1), UVM_LOW)
            `uvm_info("SETVAL", $sformatf("val2 is %d before get", val2), UVM_LOW)
            `uvm_info("SETVAL", $sformatf("str1 is %s before get", str1), UVM_LOW)
            get_config_string("str1", str1);
            /* get_config_int("val3", val2); */
            `uvm_info("SETVAL", $sformatf("val1 is %d after get", val1), UVM_LOW)
            `uvm_info("SETVAL", $sformatf("val2 is %d after get", val2), UVM_LOW)
            `uvm_info("SETVAL", $sformatf("str1 is %s after get", str1), UVM_LOW)
        endfunction
    endclass

    class test1 extends uvm_test;
        `uvm_component_utils(test1)
        comp1 c1;
        function new(string name, uvm_component parent);
            super.new(name, parent);
        endfunction
        function void build_phase(uvm_phase phase);
            uvm_component::print_config_matches = 1;
            set_config_int("c1", "val1", 100);
            set_config_string("c1", "str1", "comp1");
            set_config_int("c1",  "val3", 11);
            c1 = comp1::type_id::create("c1", this);
        endfunction
    endclass

    initial begin
        run_test("test1");
    end
endmodule

信息打印

信息打印控制

以下代码实现了打印信息的控制过程。
对于写入文件,建立好文件,然后调用set_report_default_file。
然后通过控制函数,实现对打印信息的控制过程。控制函数会有很多很多。

点击查看代码
module object_report;
    import uvm_pkg::*;
    `include "uvm_macros.svh"

    class test1 extends uvm_test;

        integer f;

        `uvm_component_utils(test1)
        function new(string name, uvm_component parent);
            super.new(name, parent);
        endfunction
        function void build_phase(uvm_phase phase);
            f = $fopen("logfile", "w");
            set_report_default_file(f);
            set_report_severity_action(UVM_INFO, UVM_DISPLAY | UVM_LOG);
            set_report_severity_action(UVM_WARNING, UVM_DISPLAY | UVM_LOG);
            set_report_severity_action(UVM_ERROR, UVM_DISPLAY | UVM_LOG | UVM_COUNT);
            set_report_severity_action(UVM_FATAL, UVM_DISPLAY | UVM_LOG | UVM_STOP);
            set_report_verbosity_level(UVM_LOW);
        endfunction
        task run_phase(uvm_phase phase);
            uvm_report_info("RUN", "info1", UVM_MEDIUM);
            uvm_report_info("RUN", "info2", UVM_LOW);
            uvm_report_warning("RUN", "warning1", UVM_LOW);
            uvm_report_error("RUN", "error1", UVM_LOW);
            uvm_report_error("RUN", "error2", UVM_HIGH);
            uvm_report_error("RUN", "error3", UVM_LOW);
        endtask
        function void report_phase(uvm_phase phase);
            $fclose(f);
        endfunction
    endclass

    initial begin
        run_test("test1");
    end
endmodule

打印前控制的HOOK

如下:
默认UVM_LOW以下打印,然后是UVM_CALL_HOOK使能。、

点击查看代码
module report_hook;
    import uvm_pkg::*;
    `include "uvm_macros.svh"

    class test1 extends uvm_test;
        integer f;
        `uvm_component_utils(test1)
        function new(string name, uvm_component parent);
            super.new(name, parent);
        endfunction

        function void build_phase(uvm_phase phase);
            set_report_severity_action(UVM_ERROR, UVM_DISPLAY | UVM_CALL_HOOK);
            set_report_verbosity_level(UVM_LOW);
        endfunction

        task run_phase(uvm_phase phase);
            uvm_report_info("RUN", "info1", UVM_MEDIUM);
            uvm_report_info("RUN", "info2", UVM_LOW);
            uvm_report_warning("RUN", "warning1", UVM_LOW);
            uvm_report_error("RUN", "error1", UVM_LOW);
            uvm_report_error("RUN", "error2", UVM_HIGH);
            uvm_report_error("RUN", "error3", UVM_LOW);
        endtask

        function bit report_hook(string id, string message, int verbosity, string filename, int line);
            uvm_report_info("RPTHOOK", $sformatf("%s : %s", id, message), UVM_LOW);
            return 1;
        endfunction
        function bit report_error_hook(string id, string message, int verbosity, string filename, int line);
            uvm_report_info("ERRHOOK", $sformatf("%s : %s", id, message), UVM_LOW);
            return 1;
        endfunction
    endclass

    initial begin
        run_test("test1");
    end
endmodule

image

uvm组件

driver的seq

uvm_seq_item_pull_port seq_item_port

uvm_algorithm_comparator

更高端的通用比较类,需要实现compare、conver2string、transform函数。

双向通信

点击查看代码
module tlm_transport;
    import uvm_pkg::*;
    `include "uvm_macros.svh"

    class itrans extends uvm_transaction;
        int id;
        int data;
        function new(string name, uvm_component parent);
            super.new(name, parent);
        endfunction
    endclass

    class otrans extends uvm_transaction;
        int id;
        int data;
        function new(string name, uvm_component parent);
            super.new(name, parent);
        endfunction
    endclass

    class comp1 extends uvm_component;
        uvm_blocking_transport_port #(itrans, otrans) bt_port;
        `uvm_component_utils(comp1)
        function new(string name, uvm_component parent);
            super.new(name, parent);
            bt_port = new("bt_port", this);
        endfunction
        task run_phase(uvm_phase phase);
            itrans itr;
            otrans otr;
            int trans_num = 6;
            for(int i=0; i<trans_num; i++) begin
                itr = new("itr", this);
                itr.id = i;
                itr.data = 'h10 + i ;
                this.bt_port.transport(itr, otr);
                `uvm_info("TRSPT", $sformatf("put itrans id: 'h%0x , data: 'h%0x | get otrans id: 'h%0x , data: 'h%0x ", 
                    itr.id, itr.data, otr.id, otr.data), UVM_LOW)
            end
        endtask
    endclass

    class comp2 extends uvm_component;
        uvm_blocking_transport_imp #(itrans, otrans, comp2) bt_imp;
        `uvm_component_utils(comp2)
        function new(string name, uvm_component parent);
            super.new(name, parent);
            bt_imp = new("bt_imp", this);
        endfunction
        task transport(itrans req, output otrans rsp);
            rsp = new("rsp", this);
            rsp.id = req.id;
            rsp.data = req.data <<  8;
        endtask
    endclass

    class env1 extends uvm_env;
        comp1 c1;
        comp2 c2;
        `uvm_component_utils(env1)

        function new(string name, uvm_component parent);
            super.new(name, parent);
        endfunction

        function void build_phase(uvm_phase phase);
            super.build_phase(phase);
            c1 = comp1::type_id::create("c1", this);
            c2 = comp2::type_id::create("c2", this);
        endfunction: build_phase

        function void connect_phase(uvm_phase phase);
            super.connect_phase(phase);
            c1.bt_port.connect(c2.bt_imp);
        endfunction: connect_phase
    endclass

    class test1 extends uvm_test;
        `uvm_component_utils(test1)
        env1 env;
        function new(string name, uvm_component parent);
            super.new(name, parent);
        endfunction
        function void build_phase(uvm_phase phase);
            env = env1::type_id::create("env", this);
        endfunction
    endclass

    initial begin
        run_test("test1");
    end
endmodule


// UVM_INFO @ 0: reporter [RNTST] Running test test1...
// UVM_INFO @ 0: uvm_test_top.env.c1 [TRSPT] put itrans id: 'h0 , data: 'h10 | get otrans id: 'h0 , data: 'h1000 
// UVM_INFO @ 0: uvm_test_top.env.c1 [TRSPT] put itrans id: 'h1 , data: 'h11 | get otrans id: 'h1 , data: 'h1100 
// UVM_INFO @ 0: uvm_test_top.env.c1 [TRSPT] put itrans id: 'h2 , data: 'h12 | get otrans id: 'h2 , data: 'h1200 
// UVM_INFO @ 0: uvm_test_top.env.c1 [TRSPT] put itrans id: 'h3 , data: 'h13 | get otrans id: 'h3 , data: 'h1300 
// UVM_INFO @ 0: uvm_test_top.env.c1 [TRSPT] put itrans id: 'h4 , data: 'h14 | get otrans id: 'h4 , data: 'h1400 
// UVM_INFO @ 0: uvm_test_top.env.c1 [TRSPT] put itrans id: 'h5 , data: 'h15 | get otrans id: 'h5 , data: 'h1500

TLM2.0

特点

双向通信,支持blocking和nonblocking两种方式。

blocking方式需要在一次传输过程中request和response,实现方法为:b_transport,对应任务:

task b_transport(trans, delay)

nonblocking方式将request和response分为两个独立的单向传输,两个传输整体视为一个传输过程。
实现方法为:nb_transport_fw, nb_transport_bw。
对应函数:

function uvm_tlm_sync_e nb_transport_fw(trans, p, delay);
function uvm_tlm_sync_e nb_transport_bw(trans, p, delay);

trans:uvm_tlm_generic_payload类,唯一的trans
p为:做状态同步的部分
fw:request发送通道
bw: response发送通道
delay: uvm_til_time类,标定延迟时间

端口

端口是继承于uvm_port_base的,
image

blocking方式的代码

点击查看代码
module tlm2_socket;
    import uvm_pkg::*;
    `include "uvm_macros.svh"

    class comp1 extends uvm_component;
        uvm_tlm_b_initiator_socket b_ini_skt;
        `uvm_component_utils(comp1)
        function new(string name, uvm_component parent);
            super.new(name, parent);
            b_ini_skt = new("b_ini_skt", this);
        endfunction
        task run_phase(uvm_phase phase);
            byte unsigned data[] = {1, 2, 3, 4, 5, 6, 7, 8};
            uvm_tlm_generic_payload pl = new("pl");
            uvm_tlm_time delay = new("delay");
            pl.set_address('h0000F000);
            pl.set_data_length(8);
            pl.set_data(data);
            pl.set_byte_enable_length(8);
            pl.set_write();
            delay.incr(0.3ns, 1ps);
            `uvm_info("INITRSP", $sformatf("initiated a trans at %0d ps", $realtime()), UVM_LOW)
            b_ini_skt.b_transport(pl, delay);
        endtask
    endclass

    class comp2 extends uvm_component;
        uvm_tlm_b_target_socket #(comp2) b_tgt_skt;
        `uvm_component_utils(comp2)
        function new(string name, uvm_component parent);
            super.new(name, parent);
            b_tgt_skt = new("b_tgt_skt", this);
        endfunction
        task b_transport(uvm_tlm_generic_payload pl, uvm_tlm_time delay);
            `uvm_info("TGTTRSP", $sformatf("received a trans at %0d ps", $realtime()), UVM_LOW)
            pl.print();
            #(delay.get_realtime(1ps));
            pl.set_response_status(UVM_TLM_OK_RESPONSE);
            `uvm_info("TGTTRSP", $sformatf("completed a trans at %0d ps", $realtime()), UVM_LOW)
            pl.print();
        endtask
    endclass

    class env1 extends uvm_env;
        comp1 c1;
        comp2 c2;
        `uvm_component_utils(env1)

        function new(string name, uvm_component parent);
            super.new(name, parent);
        endfunction

        function void build_phase(uvm_phase phase);
            super.build_phase(phase);
            c1 = comp1::type_id::create("c1", this);
            c2 = comp2::type_id::create("c2", this);
        endfunction: build_phase

        function void connect_phase(uvm_phase phase);
            super.connect_phase(phase);
            c1.b_ini_skt.connect(c2.b_tgt_skt);
        endfunction: connect_phase
    endclass

    class test1 extends uvm_test;
        `uvm_component_utils(test1)
        env1 env;
        function new(string name, uvm_component parent);
            super.new(name, parent);
        endfunction
        function void build_phase(uvm_phase phase);
            env = env1::type_id::create("env", this);
        endfunction
        task run_phase(uvm_phase phase);
            super.run_phase(phase);
            phase.raise_objection(this);
            #1us;
            phase.drop_objection(this);
        endtask
    endclass

    initial begin
        run_test("test1");
    end
endmodule

运行命令

vcs -sverilog -R -ntb_opts uvm-1.1 -timescale="1ps/1ps" taa.sv

运行结果:

点击查看代码
UVM_INFO @ 0: reporter [RNTST] Running test test1...
UVM_INFO taa.sv(22) @ 0: uvm_test_top.env.c1 [INITRSP] initiated a trans at 0 ps
UVM_INFO taa.sv(35) @ 0: uvm_test_top.env.c2 [TGTTRSP] received a trans at 0 ps
-------------------------------------------------------------------------------
Name               Type                       Size  Value                      
-------------------------------------------------------------------------------
pl                 uvm_tlm_generic_payload    -     @505                       
  address          integral                   64    'hf000                     
  command          uvm_tlm_command_e          32    UVM_TLM_WRITE_COMMAND      
  response_status  uvm_tlm_response_status_e  32    UVM_TLM_INCOMPLETE_RESPONSE
  streaming_width  integral                   32    'h0                        
  data             darray(byte)               8     -                          
    [0]            byte                       8     'h01 x                     
    [1]            byte                       8     'h02 x                     
    [2]            byte                       8     'h03 x                     
    [3]            byte                       8     'h04 x                     
    [4]            byte                       8     'h05 x                     
    [5]            byte                       8     'h06 x                     
    [6]            byte                       8     'h07 x                     
    [7]            byte                       8     'h08 x                     
  extensions       aa(obj,obj)                0     -                          
-------------------------------------------------------------------------------
UVM_INFO taa.sv(39) @ 300: uvm_test_top.env.c2 [TGTTRSP] completed a trans at 300 ps
-------------------------------------------------------------------------
Name               Type                       Size  Value                
-------------------------------------------------------------------------
pl                 uvm_tlm_generic_payload    -     @505                 
  address          integral                   64    'hf000               
  command          uvm_tlm_command_e          32    UVM_TLM_WRITE_COMMAND
  response_status  uvm_tlm_response_status_e  32    UVM_TLM_OK_RESPONSE  
  streaming_width  integral                   32    'h0                  
  data             darray(byte)               8     -                    
    [0]            byte                       8     'h01 x               
    [1]            byte                       8     'h02 x               
    [2]            byte                       8     'h03 x               
    [3]            byte                       8     'h04 x               
    [4]            byte                       8     'h05 x               
    [5]            byte                       8     'h06 x               
    [6]            byte                       8     'h07 x               
    [7]            byte                       8     'h08 x               
  extensions       aa(obj,obj)                0     -                    
-------------------------------------------------------------------------
UVM_INFO /home/synopsys/vcs-mx/O-2018.09-1/etc/uvm-1.1/base/uvm_objection.svh(1273) @ 1000000: reporter [TEST_DONE] 'run' phase is ready to proceed to the 'extract' phase

--- UVM Report Summary ---

** Report counts by severity
UVM_INFO :    5
UVM_WARNING :    0
UVM_ERROR :    0
UVM_FATAL :    0
** Report counts by id
[INITRSP]     1
[RNTST]     1
[TEST_DONE]     1
[TGTTRSP]     2
$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              1000000

posted @ 2022-02-24 14:46  大浪淘沙、  阅读(284)  评论(0)    收藏  举报