クラスのメンバーをプリントする為には、print()メソッドを使用します。このメソッドが正しく 動作する為には、`uvm_fieldマクロを設定する必要があります。UVMは次の三種類のプリンター を定義しています。
プリンター 機能
uvm_default_table_printer 表形式にプリントします。最も複雑なプリント処理となりま
す。
uvm_default_tree_printer 各行に名称と値の対をプリントします。
uvm_default_line_printer 名称と値の対を一行にプリントします。
uvm_default_table_printer は複雑である為、処理時間が最も多く必要なプリンターであると言われ
ています。プリント件数が膨大な数になる場合には、他のプリンターの使用が勧められます。次 に、これらの相違を示します。先ず、データを以下の様に定義します。
class my_env extends uvm_env;
get_consumer_ap con_ap;
subscriber sub1, sub2;
`uvm_component_utils(my_env)
function new(string name,uvm_component parent);
super.new(name,parent);
con_ap = new("con_ap",this);
sub1 = new("sub1",this);
sub2 = new("sub2",this);
endfunction
function void connect_phase(uvm_phase phase);
con_ap.analysis_port.connect(sub1.analysis_export);
con_ap.analysis_port.connect(sub2.analysis_export);
endfunction endclass
class my_obj extends uvm_object;
bit [7:0] request;
bit [7:0] grant;
bit [31:0] data[8];
`uvm_object_utils_begin(my_obj)
`uvm_field_int(request,UVM_DEFAULT);
`uvm_field_int(grant,UVM_DEFAULT)
`uvm_field_sarray_int(data,UVM_DEFAULT)
`uvm_object_utils_end
function new(string name="my_obj");
super.new(name);
endfunction endclass
プリント処理は以下の様にします。同じ内容を三つのプリンターを使用してプリントする事にし ます。
uvm_default_table_printerの結果は以下の様になります。
uvm_default_tree_printerの結果は以下の様になります。
module top;
my_obj obj;
initial begin
obj = my_obj::type_id::create();
obj.request = 8'hf0;
obj.grant = 8'h01;
obj.data = { 1, 2, 3, 4, 5, 6, 7, 8 };
obj.print();
obj.print(uvm_default_tree_printer);
obj.print(uvm_default_line_printer);
end endmodule
--- Name Type Size Value --- my_obj my_obj - @272 request integral 8 'hf0 grant integral 8 'h1 data sa(integral) 8 - [0] integral 32 'h1 [1] integral 32 'h2 [2] integral 32 'h3 [3] integral 32 'h4 [4] integral 32 'h5 [5] integral 32 'h6 [6] integral 32 'h7 [7] integral 32 'h8 ---
my_obj: (my_obj@272) { request: 'hf0
grant: 'h1 data: { [0]: 'h1 [1]: 'h2 [2]: 'h3 [3]: 'h4 [4]: 'h5 [5]: 'h6 [6]: 'h7 [7]: 'h8 }
}
uvm_default_line_printerの結果は以下の様になります。
プリンターの設定には、uvm_default_printer を使用すると便利です。トップ・モジュールで以下 の様に設定するとプリント形式が変わります。
2.3.2 アレイのプリント
クラス・インスタンスをプリントすると全てのメンバーがプリントされますが、アレイのプリン トに関しては制限が付きます。例えば、アレイ・サイズが 30 であるとすると、最初の 5 個と最 後の5個のアレイ要素がプリントされます。
コンフィギュレーションの設定変更で使用した例に於いて data_sizeを 30に変更してみると以下 の様にプリントされます。
多くの場合、トランザクションとして使用するアレイはダイナミックであり、アレイ・サイズを ランダムに決定します。その様な場合、全てのアレイ要素をプリントする意味が余りありません。
その為に、アレイ要素のプリントにはこの様な配慮がされていると考えられます。ダイナミッ my_obj: (my_obj@272) { request: 'hf0 grant: 'h1 data: { [0]: 'h1 [1]: 'h2 [2]: 'h3 [3]: 'h4 [4]: 'h5 [5]: 'h6 [6]: 'h7 [7]:
'h8 } }
module top;
import uvm_pkg::*;
...
initial begin ...
uvm_default_printer = uvm_default_tree_printer;
run_test();
end
endmodule
--- Name Type Size Value --- test my_comp - @280 header_name string 11 data[0..29]
data_size integral 32 'h1e data da(integral) 30 - [0] integral 32 'h0 [1] integral 32 'h1 [2] integral 32 'h2 [3] integral 32 'h3 [4] integral 32 'h4 ... ... ... ...
[25] integral 32 'h19 [26] integral 32 'h1a [27] integral 32 'h1b [28] integral 32 'h1c [29] integral 32 'h1d ---
プリント制御には次のクラスが関連を持ちます。
uvm_printer
uvm_printer_knobs
uvm_printer はプロパーティとして uvm_printer_kbobs のインスタンスを持っています。そして、
uvm_printer_knobs ク ラ ス は プ リ ン ト 制 御 の プ ロ パ ー テ ィ を 持 っ て い ま す 。 以 下 に uvm_printer_knobsクラスの一部を紹介します。
UVM のソース・コードを見ると、アレイの最初と最後の 5 個ずつプリントする様に設定されて いるのが分かります。同時に、begin_elements に-1 を設定すると全ての要素をプリントする事が 出来る事も分かります。
全てのアレイ要素をプリントする為にはプリンターのノブを使用して、プリント制限を変更しま す。以下は、その一例です。他の方法もあると思います。
class uvm_printer_knobs;
...
// Variable: begin_elements //
// Defines the number of elements at the head of a list to print.
// Use -1 for no max.
int begin_elements = 5;
// Variable: end_elements //
// This defines the number of elements at the end of a list that // should be printed.
int end_elements = 5;
...
endclass
module top;
import uvm_pkg::*;
import Pkg::*;
my_comp test;
string print_option;
initial begin
// fix the configuration.
uvm_config_db#(string)::set(null,"test",
"header_name","data[0..29]");
uvm_config_db#(int)::set(null,"test","data_size",30);
//
// command line parameters.
//
if( !$value$plusargs("PRINT=%s",print_option) ) print_option = "short";
if( print_option.tolower() == "all" )
uvm_default_printer.knobs.begin_elements = -1;
この例では、プリンターの制御をコマンド・ラインの指示で変更する様にしています。コマン ド・ラインで以下の様にタイプするとアレイ要素を全てプリントします。
ソース・コードを見て分かる様に、入力したパラメータを小文字に変換しています。従って、
でも同様の効果を得ます。
コマンド・ラインのパラメータの取得にSystemVerilogの$value$plusargs関数を使用していますが、
UVM にも同種の関数が存在します。但し、使用方法は若干異なります。ここでは、敢えて標準 的な関数を使用しました。アレイ要素を全てプリントすると以下の様になります。
// create components.
test = my_comp::type_id::create("test",null);
run_test();
end endmodule
svsim +PRINT=ALL
svsim +PRINT=all
--- Name Type Size Value --- test my_comp - @280 header_name string 11 data[0..29]
data_size integral 32 'h1e data da(integral) 30 - [0] integral 32 'h0 [1] integral 32 'h1 [2] integral 32 'h2 [3] integral 32 'h3 [4] integral 32 'h4 [5] integral 32 'h5 [6] integral 32 'h6 [7] integral 32 'h7 [8] integral 32 'h8 [9] integral 32 'h9 [10] integral 32 'ha [11] integral 32 'hb [12] integral 32 'hc [13] integral 32 'hd [14] integral 32 'he [15] integral 32 'hf [16] integral 32 'h10 [17] integral 32 'h11 [18] integral 32 'h12 [19] integral 32 'h13 [20] integral 32 'h14