class(クラス)の基本的な使い方を紹介します
はじめに
SystemVerilogではclass(クラス)を使用してオブジェクト指向的にコーデイングできます
論理合成対象のRTLではあまり使用しませんが、検証環境ではよく使用します(ex. UVM)
今回は、クラスの基本的な使用方法について紹介します
サンプルコード
以下サンプルコードです。
module test;
class base_test; // クラス名
logic [3:0] data; // クラスの要素(変数)
function new(); // クラスの要素(初期化関数)
data = 1;
endfunction
function void print; // クラスの要素(関数)
$display("====================");
$display("data : %d d", data);
$display("====================");
endfunction
endclass
initial begin
base_test comp; // base_testクラス型のcompを作成
comp = new(); // new()で初期化する
comp.print; // <クラス>.<関数名>でクラスの要素にアクセスできる
$finish();
end
endmodule
実行すると、以下のように出力されます
====================
data : 1 d
====================
では、中身について解説していきます
サンプルコードの解説
クラスは
class <クラス名>; // クラス名
endclass
で宣言できます
クラスの要素を追加したいときはclass-endclass内で変数を宣言します
class base_test; // クラス名
logic [3:0] data; // クラスの要素(変数)
endclass
クラスに関数を登録する場合も同様に、class-endclass内でfunction/taskを宣言します
class base_test; // クラス名
logic [3:0] data; // クラスの要素(変数)
function void print; // クラスの要素(関数)
$display("====================");
$display("data : %d d", data);
$display("====================");
endfunction
endclass
クラスの要素、dataの中身を標準出力する関数です
次に、クラスの初期化関数を宣言します。関数名はnew()で固定です
class base_test; // クラス名
logic [3:0] data; // クラスの要素(変数)
function new(); // クラスの要素(初期化関数)
data = 1;
endfunction
function void print; // クラスの要素(関数)
$display("====================");
$display("data : %d d", data);
$display("====================");
endfunction
endclass
初期化されると、dataに1が入ります
これでクラスを作成できました
次に作成したクラスを使ってみます
まず、作成したクラス、base_testクラス型の変数を宣言します
initial begin
base_test comp; // base_testクラス型のcompを作成
end
次に、作成したクラスを初期化関数(new)を使用して初期化します
初期化は、
<クラス型> = new();
で行われます。
initial begin
base_test comp; // base_testクラス型のcompを作成
comp = new(); // new()で初期化する
end
初期化すると、base_testクラス型の要素のdataに1が入ります
(base_testのnew()の中身をもう一度確認してみてください)
初期化が完了したので、base_testクラス型の中で宣言したprintを使用します
initial begin
base_test comp; // base_testクラス型のcompを作成
comp = new(); // new()で初期化する
comp.print; // <クラス>.<関数名>でクラスの要素にアクセスできる
end
以上がクラスの基本的な使用方法でした
クラスの外にfunction/taskの中身を書く(extern)
クラスの要素が多いときに関数の中身をクラス内に書いていると、可読性が落ちていきます
そこで、関数の宣言のみを行い、中身をクラス外に書くことができます
そのとき使用するのがexternです
以下、サンプルコードです
module tb;
class base_test;
logic [3:0] data;
function new();
data = 1;
endfunction
extern function void print();
endclass
function void base_test::print(); // base_testのprintの中身を書く
$display("====================");
$display("data : %d d", data);
$display("====================");
endfunction
initial begin
base_test comp;
comp = new();
comp.print;
$finish();
end
endmodule
class-endclass内でexternでprintを宣言しました
そしてclass-endclass外で
<クラス名>::<関数名>
でexternで宣言した関数の中身を書くことができます
クラスを継承する(extends)
クラスなので、もちろん継承できます
クラスを継承するときはextendsを使って以下のように書きます
class <新しいクラス名> extends <継承されるクラス>
さきほど作成したbase_testクラスを継承してnew_testクラスを作成してみます
module tb;
class base_test;
logic [3:0] data;
function new();
data = 1;
endfunction
function void print();
$display("====================");
$display("data : %d d", data);
$display("====================");
endfunction
endclass
class new_test extends base_test; // base_testを継承してnew_testを作成
function new();
super.print(); // 初期化時にbase_testのprint関数を実行
endfunction
function void countup(); // dataに1を加算するcountup関数を要素に追加
data = data + 1;
endfunction
endclass
initial begin
new_test comp;
comp = new();
comp.print;
comp.countup();
comp.print;
$finish();
end
endmodule
実行結果
====================
data : 1 d
====================
====================
data : 1 d
====================
====================
data : 2 d
====================
継承元と継承したクラスで同じ要素を作成している場合
super.<要素>で継承元
this.<要素>で継承したクラス
の要素を呼び出せます
クラスをパラメータ化する
moduleのようにクラスもパラメタライズできます
class <クラス名> #(parameter <パラメータ名> = <値>);
// クラスの中身
endclass
新しいクラスのオブジェクトを宣言するときは以下のように使用します
<クラス名> #(.<パラメータ名>(<値>)) <オブジェクト名>;
以下、サンプルコードです
module tb;
class base_test #(parameter DATA = 3);
function void print();
$display("%d", DATA);
endfunction
endclass
initial begin
base_test a;
base_test #(1) b;
a = new();
b = new();
a.print();
b.print();
$finish();
end
endmodule
実行結果
3
1
まとめ
SystemVerilogのclass(クラス)の基本的な使い方についてまとめました
検証は設計の倍の時間がかかると言われており、検証資産を再利用することが重要です
classを使ってオブジェクト指向的に検証環境を作成することで再利用性を高めることが可能です
コメント