テストプログラムを作成していると、正規表現での文字列マッチングの機能が欲しくなることがあります。残念ながらSystem Verilogはその機能を提供していませんが、UVMにはサポートがあります。ここではその使用方法と注意点を説明します。
#使い方
function int uvm_re_match(string re, string str);
reが正規表現、strがマッチングの対象となる文字列です。ちょっと注意が必要なのが戻り値で、マッチした場合に0 それ以外の場合に非0のエラーコードを返します。本メソッドの内部ではDPI経由でCの正規表現ライブラリのregcomp()/regexec()を呼び出しており、この関数の作法に従っているためです。Cの標準関数では、多くの場合成功の場合0、それ以外の場合は非0のエラーコードを返すのが通例になっています。
サンプルプログラムとその実行結果を以下に示します。
サンプルプログラム:
import uvm_pkg::*;
`include "uvm_macros.svh"
program top();
initial begin
string orig[$] = {"fizz",
"buzz",
"fizz buzz"};
string sel[$];
`uvm_info("", "==== All Items ====", UVM_NONE);
foreach (orig[i]) begin
`uvm_info("", orig[i], UVM_NONE);
end
sel = orig.find with (!uvm_re_match("^f.*z$", item));
`uvm_info("", "==== Selected Items ====", UVM_NONE);
foreach (sel[i]) begin
`uvm_info("", sel[i], UVM_NONE);
end
end
endprogram
実行結果:
UVM_INFO testbench.sv(11) @ 0: reporter [] ==== All Items ====
UVM_INFO testbench.sv(13) @ 0: reporter [] fizz
UVM_INFO testbench.sv(13) @ 0: reporter [] buzz
UVM_INFO testbench.sv(13) @ 0: reporter [] fizz buzz
UVM_INFO testbench.sv(17) @ 0: reporter [] ==== Selected Items ====
UVM_INFO testbench.sv(19) @ 0: reporter [] fizz
UVM_INFO testbench.sv(19) @ 0: reporter [] fizz buzz
用途の一例としては、名前が特定の法則に合致するレジスタクラスのオブジェクトのリストを取得するのに使えます。以下はmy_uvm_reg_mapに登録されているレジスタクラスのオブジェクトのうち、名前がMPUで始まる全てのハンドルを取得してmirror()するコードです。
uvm_reg all_regs[$];
uvm_reg selected_regs[$];
my_uvm_reg_map.get_registers(all_regs);
selected_regs = all_regs.find with (!uvm_re_match("^MPU_", item.get_name()));
foreach(selected_regs[i]) begin
selected_regs[i].mirror();
end
#注意点
上記の通り、正規表現の取り扱いはSystem Verilogやシミュレータが行っているのではなく、DPIでリンクされているCのライブラリが行っています。正規表現にはさまざまな拡張表現がありますが、それらを使用すると同じシミュレータを使用していても、異なるライブラリがリンクされた場合に互換性の問題が発生する可能性があります。
また、コンパイル時にdefineでUVM_NO_DPIを定義した場合、DPIが使用されず、代わりにSystem Verilogの同名メソッドが使用されます。uvm_re_matchメソッドもDPI経由ではなく、純粋なSystem Verilogのメソッドに置き換えられます。ただしこのメソッドではマッチング文字列が正規表現ではなく、globとして解釈されます。本defineの有無で動作が変わりますので、この点にもご注意ください。
#リファレンス
本メソッドはドキュメント化されていません。UVM_Class_ReferenceManualのuvm_resource_baseの説明で少し名前が出ている程度です。
dpi/uvm_regex.ccが本メソッドのソースコードとなりますのでそちらを参照ください。dpi/uvm_regex.svhというファイルもありますが、こちらはDPIを使用しない場合に適用される純粋なSystem Verilogのメソッドとなっています。UVM_NO_DPIをdefineしてコンパイルした場合はこちらが使用されます。