UVM Ojbect Print

2023-10-31
UVM

uvm_object是衍生所有其他UVM相關的data和component的base class。所以uvm_object有一系列通用的function讓衍生的class使用。

Example

範例的是使用 UVM 自動化macro來print變數內容。 Object class 是繼承了 uvm_object ,所以繼承了父類別中的所有功能。在Object class中宣告了一些不同data type的變數,然後用print function印出這些變數。

對於每種不同的資料類型,都有對應的``uvm_field_*` macro讓使用者使用與其data type相對應的macro註冊。UVM_DEFAULT這個FLAG表示這個變數要套用於物件所有預設 UVM 的自動化macro,就是copy、print、compare、record和pack。想知道有哪些FLAG可參考uvm-1.2\docs\html\src\base\uvm_object_globals.svh。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Object extends uvm_object;
e_bool bool;
bit[3:0] bit_var;
byte byte_arr[4];
int int_queue[$];
string str;

`uvm_object_utils_begin(Object)
`uvm_field_enum(e_bool, bool, UVM_DEFAULT)
`uvm_field_int(bit_var, UVM_DEFAULT)
`uvm_field_sarray_int(byte_arr, UVM_DEFAULT)
`uvm_field_queue_int(int_queue, UVM_DEFAULT)
`uvm_field_string(str, UVM_DEFAULT)
`uvm_object_utils_end
function new(string name = "Object");
super.new(name);
str = name;
bit_var = $random;
endfunction
endclass

接著在base_test裡面產生Object的instance然後用print function印出物件的內容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class base_test extends uvm_test;
`uvm_component_utils(base_test)
function new(string name = "base_test", uvm_component parent = null);
super.new(name, parent);
endfunction

function void build_phase(uvm_phase phase);
Object obj = Object::type_id::create("obj");
obj.print();
// obj.randomize();

endfunction
endclass

module tb;
initial begin
$display("start");
run_test("base_test");
end
endmodule

output

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# start
# UVM_INFO @ 0: reporter [RNTST] Running test base_test...
# ---------------------------------------
# Name Type Size Value
# ---------------------------------------
# obj Object - @473
# bool e_bool 32 FALSE
# bit_var integral 4 'h4
# byte_arr sa(integral) 4 -
# [0] integral 8 'h0
# [1] integral 8 'h0
# [2] integral 8 'h0
# [3] integral 8 'h0
# int_queue da(integral) 0 -
# str string 6 Object
# ---------------------------------------

Using do_print()

如果想要客製化自己的print,可以實作do_print function,然後客製化自己想要的格式,但我沒仔細看,就把網頁上的範例簡單試試

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Object extends uvm_object;
e_bool bool;
bit[3:0] bit_var;
byte byte_arr[4];
int int_queue[$];
string str;

`uvm_object_utils(Object)
function new(string name = "Object");
super.new(name);
str = name;
bit_var = $random;
endfunction

virtual function void do_print(uvm_printer printer);
super.do_print(printer);
printer.print_string("1bool", bool.name());
printer.print_field("2bit_var", bit_var, $bits(bit_var), UVM_HEX);
printer.print_string("3str", str);
endfunction
endclass

output

1
2
3
4
5
6
7
8
9
10
# start
# UVM_INFO @ 0: reporter [RNTST] Running test base_test...
# ----------------------------------
# Name Type Size Value
# ----------------------------------
# obj Object - @473
# 1bool string 5 FALSE
# 2bit_var integral 4 'h0
# 3str string 6 Object
# ----------------------------------

Using sprint

UVM object也有sprint function,function的return值是以字串格式傳回格式化的內容。跟print的差別是print就是把object的內容印出來,sprint則是把內容放在return的字串上面,下面的例子是使用`uvm_info印出sprint回傳的字串

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class base_test extends uvm_test;
`uvm_component_utils(base_test)
function new(string name = "base_test", uvm_component parent = null);
super.new(name, parent);
endfunction

function void build_phase(uvm_phase phase);
Object obj = Object::type_id::create("obj");
// obj.print();
// obj.randomize();
`uvm_info(get_type_name(), $sformatf("Ojbect Contents is in below:\n %s", obj.sprint()), UVM_LOW)
endfunction
endclass

module tb;
initial begin
$display("start");
run_test("base_test");
end
endmodule

output

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# start
# UVM_INFO @ 0: reporter [RNTST] Running test base_test...
# UVM_INFO .\uvm_object_print.sv(59) @ 0: uvm_test_top [base_test] Ojbect Contents is in below:
# ---------------------------------------
# Name Type Size Value
# ---------------------------------------
# obj Object - @473
# bool e_bool 32 FALSE
# bit_var integral 4 'h4
# byte_arr sa(integral) 4 -
# [0] integral 8 'h0
# [1] integral 8 'h0
# [2] integral 8 'h0
# [3] integral 8 'h0
# int_queue da(integral) 0 -
# str string 6 Object
# ---------------------------------------