SystemVerilogではコンパイル後に値を代入することができます
その機能を応用して、コンパイル後にテストを入れ替えます
サマリ
テストファイルが大量にあるとき、DUT、テストベンチを何度もコンパイルすることになります
そこで、複数のテスト、DUT、テストベンチを一度にコンパイルしてシミュレーション時にテストを切り替えるテスト環境を作成しました
背景
ハードウェアはソフトウェアと違い、完成後の修正が容易ではないため、ガチガチにテストします
ハードウェアのテスト環境は、
・検証対象であるDUT(Design Under Test)
・DUTへの入力を作るテスト
・DUTの出力が正しいかチェックするテストベンチ
から成り立っています
テストを実行するには、DUT、実行するテスト、テストベンチをコンパイルして実行ファイルを生成します
別なテストを実行するときは、テストを切り替えてコンパイルをやり直す必要があります
なので、テストが大量にあると、DUT、テストベンチを何度もコンパイルすることになり、無駄な時間が生じます
目的
テストをまとめてコンパイルして実行時に切り替えることで、テスト全体にかかる時間を削減します
コンパイル後にテストを切り替えるテスト環境を作成する
テスト環境のイメージ図を以下に示します
DUT(Design Under Test)
テスト対象となるRTLです
dinで入力された値に1を足して出力するだけの回路です
dut.sv
module dut(
input clk,
input rst_b,
input [3:0] din,
output logic [3:0] dout
);
always_ff@(posedge clk, negedge rst_b) begin
if (!rst_b) begin
dout <= '0;
end
else begin
dout <= din + 1'b1;
end
end
endmodule
テストベンチ
DUTをインスタンスしているだけで、チェック機能はありません
tb.sv
module tb;
logic clk;
logic rst_b;
logic [3:0] din;
logic [3:0] dout;
dut #(
) u_dut(
.clk(clk),
.rst_b(rst_b),
.din(din),
.dout(dout)
);
endmodule
テスト
test1, test2の2つあります
test1はdinに’d5, test2はdinに’d15を代入するだけのテストです
test1.sv
module test1;
reg clk = 0;
always #5 clk = !clk;
reg rst_b = 0;
initial #20 rst_b = 1;
initial begin
if ($test$plusargs("test1")) begin // 実行時に+test1を指定するとTrue、しないとFalseが返ってきます
seq;
#500;
$finish;
end
end
always@* begin
if ($test$plusargs("test1")) begin // test1を実行するとき、test1で生成した信号をDUTに与えます
tb.clk = clk;
tb.rst_b = rst_b;
tb.din = din;
end
end
logic [3:0] din;
task seq;
#50;
din = 5;
$display("din %b:%d", din, din);
#10;
$display("dout %b:%d", tb.dout, tb.dout);
endtask
endmodule
test2.sv
module test2;
reg clk = 0;
always #5 clk = !clk;
reg rst_b = 0;
initial #20 rst_b = 1;
initial begin
if ($test$plusargs("test2")) begin
seq;
#500;
$finish;
end
end
always@* begin
if ($test$plusargs("test2")) begin
tb.clk = clk;
tb.rst_b = rst_b;
tb.din = din;
end
end
logic [3:0] din;
task seq;
#50;
din = 14;
$display("din %b:%d", din, din);
#10;
$display("dout %b:%d", tb.dout, tb.dout);
endtask
endmodule
シミュレーションを実行する
シミュレーションはIcarus Verilogを使用します
まず、コンパイルします
iverilog -g2009 tb.sv dut.sv test1.sv test2.sv
コンパイルが成功したらa.outが生成されます
同じ実行ファイルでtest1, test2をそれぞれ実行してみましょう
test1を実行する
test1はdinに’d5を入れるテストです
test1を実行してみましょう
vvp a.out +test1
# 実行結果
# din 0101:5
# dout 0110:6
test2を実行する
test2はdinに’d14を入れるテストです
test2を実行してみましょう
vvp a.out +test2
# 実行結果
# din 1110:14
# dout 1111:15
同じ実行ファイルでテストを切り替えることができました
まとめ
DUT、テストベンチ、テストをまとめてコンパイルして、シミュレーション時に切り替えられました。
コメント