
田中太郎
RTLをテストするときの入力データをテストファイルに書き込むのではなく
シミュレーション実行時に引数として渡してみました
サマリ
DUTに与える入力データをちょい編したいとき、
テストファイル書き換え→コンパイル→シミュレーション実行
をやり直さないために、シミュレーション実行時に引数で入力データを与える方法を試しました
背景
RTLのテストを行うとき、テストファイルに値を書くと
テスト編集→コンパイル→シミュレーション→値の確認→テスト編集→…
を繰り返す必要があります
値だけを編集する場合はコンパイルからやり直すのはおっくうです
目的
シミュレーション実行時に入力データを渡すことで、コンパイルからやり直さない
テスト環境の作成
テスト環境は以下です
・DUT(Design Under Test)(dut.sv)
・テストベンチ(tb.sv)
・テストファイル(test.sv)
dut.sv
din に1を加算して出力する回路です
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
tb.sv
dutをインスタンスしているだけです
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
test.sv
clk, rst_b, dinを生成してtb.svに値を代入しています
test.svでは$value$plusargsで引数を受け取ります
module test;
reg clk = 0;
always #5 clk = !clk; // クロックを生成
reg rst_b = 0;
initial #20 rst_b = 1; // リセットを生成
logic [3:0] din;
initial begin
if ($value$plusargs("din=%d", din)) begin // dinに値を与えるとTrue、与えないとFalseを返す
seq;
end
else begin
$display("din has no value.");
end
$finish;
end
always@* begin // tb.svに値を代入しています
if ($value$plusargs("din=%d", din)) begin
tb.clk = clk;
tb.rst_b = rst_b;
tb.din = din;
end
end
task seq;
#50;
$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 .\test.sv
コンパイルが成功するとa.outが生成されます
実行してみましょう
引数なし
vvp .\a.out
# 実行結果
# din has no value.
引数あり
vvp .\a.out +din=10
# 実行結果
# din 1010:10
# dout 1011:11
コンパイル後に引数を与えてシミュレーションを実行することができました
まとめ
テストファイルの値を編集してコンパイルをやり直すのが面倒なので
シミュレーション実行時に値を渡す方法を試しました
コメント