VerilogファイルI/Oの完全ガイド:オープン、読み取り、書き込み、クローズ
VerilogにおけるファイルI/Oの概要
Verilogには、ファイルを開き、値をファイルに出力し、ファイルから値を読み取って変数に格納し、ファイルを閉じるためのシステムタスクおよび関数が用意されています。これらを活用することで、シミュレーション中のデータログ記録、テストベクタの外部ファイルからの読み込み、結果のファイル出力などが可能になります。
ファイルのオープンとクローズ
ファイル操作の第一歩は、$fopenでファイルを開き、ファイルディスクリプタ(ハンドラ)を取得することです。処理が完了したら$fcloseで確実にクローズします。
module tb;
integer fd; // ファイルディスクリプタを格納する変数
initial begin
// "my_file.txt" を書き込みモードでオープンし、ハンドラを fd に格納
fd = $fopen("my_file.txt", "w");
// ファイル操作...
// ファイルをクローズ
$fclose(fd);
end
endmodule
ファイルオープンモード一覧
$fopenの第2引数で指定するモード文字列の種類と意味は以下の通りです。
| モード | 説明 |
|---|---|
| "r" / "rb" | 読み取り専用でオープン |
| "w" / "wb" | 書き込み用に新規作成。既存ファイルは切り詰められ上書きされる |
| "a" / "ab" | 追記モードでオープン。ファイルがなければ新規作成 |
| "r+" / "r+b" / "rb+" | 読み書き両用でオープン |
| "w+" / "w+b" / "wb+" | 読み書き用に切り詰めまたは新規作成 |
| "a+" / "a+b" / "ab+" | 追記または新規作成(EOF位置で更新) |
ファイルへの書き込み
Verilogには、コンソール出力用の$displayなどに対応するファイル出力用システム関数が用意されています。
| 関数 | 説明 |
|---|---|
| $fdisplay | $displayと同様だが、ファイルへ出力 |
| $fwrite | $writeと同様だが、ファイルへ出力(改行なし) |
| $fstrobe | $strobeと同様だが、ファイルへ出力(非ブロッキング代入後の最終値) |
| $fmonitor | $monitorと同様だが、ファイルへ出力(値変化時に自動出力) |
これらの関数はデフォルトで10進数出力ですが、バイナリ、8進数、16進数出力用のバリエーションも用意されています。
| 関数 | 基数 |
|---|---|
| $fdisplay() / $fwrite() / $fstrobe() / $fmonitor() | 10進数(デフォルト) |
| $fdisplayb() / $fwriteb() / $fstrobeb() | 2進数 |
| $fdisplayo() / $fwriteo() / $fstrobeo() | 8進数 |
| $fdisplayh() / $fwriteh() / $fstrobeh() | 16進数 |
書き込みの実践例
module tb;
integer fd;
integer i;
reg [7:0] my_var;
initial begin
fd = $fopen("my_file.txt", "w");
my_var = 0;
$fdisplay(fd, "Value displayed with \$fdisplay");
#10 my_var = 8'h1A;
$fdisplay(fd, my_var); // 10進数: 26
$fdisplayb(fd, my_var); // 2進数: 00011010
$fdisplayo(fd, my_var); // 8進数: 032
$fdisplayh(fd, my_var); // 16進数: 1a
$fdisplay(fd, "Value displayed with \$fwrite");
#10 my_var = 8'h2B;
$fwrite(fd, my_var); // 改行なしで連続出力
$fwriteb(fd, my_var);
$fwriteo(fd, my_var);
$fwriteh(fd, my_var);
$fdisplay(fd, "Value displayed with \$fstrobe");
#10 my_var <= 8'h3C; // 非ブロッキング代入
$fstrobe(fd, my_var); // タイムステップ終了時の値を出力
$fstrobeb(fd, my_var);
$fstrobeo(fd, my_var);
$fstrobeh(fd, my_var);
#10 $fdisplay(fd, "Value displayed with \$fmonitor");
$fmonitor(fd, my_var);
for (i = 0; i < 5; i = i + 1) begin
#5 my_var <= i;
end
#10 $fclose(fd);
end
endmodule
シミュレーション出力例
Value displayed with $fdisplay 26 00011010 032 1a Value displayed with $fwrite 43001010110532b Value displayed with $fstrobe 60 00111100 074 3c Value displayed with $fmonitor 60 0 1 2 3 4
ファイルからの読み取り
1行ずつ読み取る:$fgets
$fgets(str, fd)は、ファイルディスクリプタfdから文字を読み取り、変数strに格納します。改行文字が読み込まれるか、strが満杯になるか、EOFに達するまで読み取ります。戻り値は読み取った文字数(エラー時は0)です。
EOFの検出:$feof
$feof(fd)は、EOFに達していれば非ゼロ、そうでなければ0を返します。
読み取りの実践例
module tb;
reg [8*45:1] str; // 最大45文字分のバッファ
integer fd;
initial begin
fd = $fopen("my_file.txt", "r");
// EOFまでループして1行ずつ読み取り
while (!$feof(fd)) begin
$fgets(str, fd);
$display("%0s", str);
end
$fclose(fd);
end
endmodule
複数引数を$fdisplayに渡す場合
$fdisplayに複数の変数を渡すと、スペースなしで順番に連結して出力されます。
module tb;
reg [3:0] a, b, c, d;
reg [8*30:0] str;
integer fd;
initial begin
a = 4'ha; b = 4'hb; c = 4'hc; d = 4'hd;
fd = $fopen("my_file.txt", "w");
$fdisplay(fd, a, b, c, d); // "10111213" と出力
$fclose(fd);
end
endmodule
文字列へのフォーマット出力:$sformat
$sformat(str, format_string, args...)を使うと、指定したフォーマットで変数を文字列として変数strに格納できます。ファイル出力せずに文字列操作したい場合に便利です。
module tb;
reg [8*19:0] str;
reg [3:0] a, b;
initial begin
a = 4'hA; b = 4'hB;
$sformat(str, "a=%0d b=0x%0h", a, b);
$display("%0s", str); // "a=10 b=0xb" と表示
end
endmodule
まとめ
$fopen/$fcloseでファイルのオープン・クローズを管理- 書き込みは用途に応じて
$fdisplay(改行あり)、$fwrite(改行なし)、$fstrobe(確定値)、$fmonitor(変化監視)を使い分け - 基数指定サフィックス(b, o, h)で2進/8進/16進出力が可能
- 読み取りは
$fgetsと$feofの組み合わせで行単位処理 $sformatで文字列変数へのフォーマット格納も可能
これらを組み合わせることで、テストベンチでの刺激データ読み込み、シミュレーション結果のログ記録、デバッグ情報のファイル出力など、実用的なファイルI/O処理が実現できます。
Verilog
- Verilogマスター:デジタル回路設計のための完全チュートリアル
- Verilog連結マスター:実践ガイド
- Verilog代入文の理解:種類、構文、ベストプラクティス
- Verilogブロッキング代入とノンブロッキング代入:違いを徹底解説
- Verilog関数のマスター:効率的なRTL設計のために
- Verilogタスクの理解:関数との違い、構文、使用法
- Verilogクロックジェネレータ:設計と実装ガイド
- Verilog数学関数のマスター:効率的なハードウェア設計のために
- Verilog $timeformatのマスター:精度と表示制御
- 任意のスコープでのVerilog timescale理解と表示
- Verilog入門:Hello World例で基本をマスター