UVMの環境構築第8回では、スコアボードの定義(作成)方法について解説していきます。
なお、ソースコードはGitHubに公開しています。
シリーズ目次
UVMの環境構築!シリーズの目次は、第1回 解説編の一番下をご覧ください。
スコアボードの概要
スコアボードはuvm_scoreboardまたはそのサブクラスを継承して定義します。
スコアボードの主な機能は、DUTの動作の確認です。次のような手順で動作の確認を行います。
- エージェントのAnalysis portから、トランザクションにより、DUTへの入力とDUTの出力を取得する。
- DUTへの入力値から、出力の期待値を生成する。(期待値生成のためのリファレンスモデルを実装)
- 期待値とDUTの出力を比較する。
スコアボードの定義方法
ベースクラスであるuvm_scoreboardでは、ほとんど何も定義されていないので、必要なポートや機能はすべてユーザーが定義します。次のような手順となります。
- エージェントからDUTの情報を受け取るためのAnalysis exportを定義する。
- DUTの情報を受け取ったときの処理write()を定義する。
my_scoreboard
それでは、ソースコードを見ながら、スコアボードの定義方法について説明します。
my_scoreboard.sv
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
| class my_scoreboard extends uvm_scoreboard;
uvm_analysis_imp #(my_item, my_scoreboard) item_collected_export;
int n_trial;
int n_error;
`uvm_component_utils(my_scoreboard)
/* Constructor */
function new(string name, uvm_component parent);
super.new(name, parent);
item_collected_export = new ("item_collected_export", this);
n_trial = 0;
n_error = 0;
endfunction
/* Build phase */
function void build_phase(uvm_phase phase);
super.build_phase(phase);
endfunction
/* Write() of item_collected_export */
function void write(my_item data);
int mult_exp = data.rst ? 0 : data.a_in * data.b_in;
if (mult_exp != data.mult_out) begin
`uvm_error(get_type_name(),
$sformatf("@%4t: a_in = %d, b_in = %d, mult_out = %d, mult_exp = %d",
$time, data.a_in, data.b_in, data.mult_out, mult_exp));
n_error++;
end
n_trial++;
endfunction
endclass |
class my_scoreboard extends uvm_scoreboard;
uvm_analysis_imp #(my_item, my_scoreboard) item_collected_export;
int n_trial;
int n_error;
`uvm_component_utils(my_scoreboard)
/* Constructor */
function new(string name, uvm_component parent);
super.new(name, parent);
item_collected_export = new ("item_collected_export", this);
n_trial = 0;
n_error = 0;
endfunction
/* Build phase */
function void build_phase(uvm_phase phase);
super.build_phase(phase);
endfunction
/* Write() of item_collected_export */
function void write(my_item data);
int mult_exp = data.rst ? 0 : data.a_in * data.b_in;
if (mult_exp != data.mult_out) begin
`uvm_error(get_type_name(),
$sformatf("@%4t: a_in = %d, b_in = %d, mult_out = %d, mult_exp = %d",
$time, data.a_in, data.b_in, data.mult_out, mult_exp));
n_error++;
end
n_trial++;
endfunction
endclass
- 1行目:uvm_scoreboardを継承して、my_scoreboardを定義します。
- 3行目:エージェントからDUTの情報を受け取るためのitem_collected_exportを定義します。
- 4~5行目:テスト結果を集計するためのフィールドを定義します。
- 7行目:UVMマクロを書きます。
- 9~15行目:コンストラクタを定義します。ここでitem_collected_exportのインスタンスを作成します。また、結果集計用フィールドを初期化します。
- 17~20行目:Build phaseを定義します。
- 22~37行目:エージェントからDUTの情報を受け取ったときの処理write()を定義します。ここでは、リファレンスモデルにより期待値を生成し、DUTの動作確認を行います。このwrite()が呼ばれるのは、エージェント内のモニターがwrite()を呼んだときです。
- 25行目:リファレンスモデルです。今回のDUTは乗算器なので、期待値はシンプルにdata.a_in * data.b_inとなります。
- 27行目:期待値とDUTからの出力の比較を行っています。期待値≠出力値であれば、その情報を表示し、n_errorをカウントアップします。
まとめ
今回は、スコアボードの定義方法について解説しました。シリーズを通してご覧いただけると、UVM検証環境が構築できるようになりますので、ぜひ他のコンポーネントの解説もご覧ください。
シリーズ目次はこちら