13
9

More than 5 years have passed since last update.

Verilogで外部テキストファイル読み込み

Posted at

Verilog-HDLのシミュレーションを行う際に、テストデータを外部ファイルに書いておき、(コンパイル時ではなく)シミュレーション実行時に読み込ませる手法はよく使われている手段です。

ファイルの読み込み方法として代表的なのは

  • ファイルをまとめて読み込む($readmem)
  • 1行づつ読み込む($fscanf)
  • の2パターンかと思いますが、今回は$fscanfを使用したケースを紹介します。

    $fscanfを使用すべきテストパターン
  • テストファイルの行数がテスト条件により可変長
  • テストデータにランダムアクセスしない(頭から流すだけ)
  • 1行に複数のデータがある
  • bin/hex/decフォーマットが混在している
  • 基本的な流れ $fopen を使用してファイルを開く $fgetc で1文字読み出す
  • EOF(ファイル終端か否か判定する)
  • $fscanf で1行分を書式付で読み出す 使用するシステムタスク $fopen (ファイルオープン)
    FILE_READER.v
    //  =================================================================
    //  テストパターンファイル読み込みモジュール
    //      未知の行数のテキストファイルを読み込み
    //      テキスト内容を出力する
    //  =================================================================
    module FILE_READER #
        (parameter  TERGET_FILE_PATH="file.txt" //読込むファイルのパス
        ,parameter  BIT_WIDE        =4                      //bit幅
        (input  wire                i_clk       //クロック
        ,input  wire                i_start     //開始トリガ(1で開始)
        ,output wire                o_end       //終了トリガ
        ,output wire[BIT_WIDE-1:0]  o_bin_dat   //読み込みデータ
        ,output wire[7:0]           o_hex_dat   
        integer             fd      =0  ;//ファイルディスクリプタ
        integer             cb      =0  ;//キャラクタバッファ
        integer             rtn     =0  ;//システムタスク戻り値
        reg[BIT_WIDE-1:0]   bin_dat =0  ;//テキストファイルの中身を受け取るFF
        reg[7:0]            hex_dat =0  ;//テキストファイルの中身を受け取るFF
        reg                 end_trg =0  ;//終了トリガ
        //出力ポートへ接続
        assign  o_end       =end_trg    ;
        assign  o_bin_dat   =bin_dat    ;
        assign  o_hex_dat   =hex_dat    ;
        //スタートトリガをクロック立上りで監視
        always@(posedge i_clk) begin:FILE_READ_SEQ
            if(i_start)begin    //開始条件
                //ファイルオープン
                //-------------------------------
                fd=$fopen(TERGET_FILE_PATH,"r");
                if(fd==0)begin
                    //オープン失敗
                    $display("File Open Error!!!!!");
                    //イベントから抜ける
                    disable FILE_READ_SEQ;
                end else begin
                    //オープン成功
                    $display("File Open OK");
                //ファイル読出しループ
                //-------------------------------
                begin:FILE_LOOP
                    forever begin                   
                        //ファイル終端に達したらループを抜ける
                        if($feof(fd) != 0)begin
                            $display("File End !!");
                            disable FILE_LOOP;
                        //クロック同期
                        @(posedge i_clk);
                        //書式付読出し
                        rtn=$fscanf(fd,"%b %h\n",bin_dat,hex_dat);
                //ファイルを閉じで終了トリガを出す
                //-------------------
                $fclose(fd);
                @(posedge i_clk);
                end_trg <=1'b1;
                bin_dat <={BIT_WIDE{1'b0}};
                hex_dat <=8'h0;
                @(posedge i_clk);
                end_trg <=1'b0;
    endmodule
            @(posedge i_clk);   i_start=1'b1;
            @(posedge i_clk);   i_start=1'b0;
            @(posedge o_end);
    endmodule
    

    Register as a new user and use Qiita more conveniently

    1. You get articles that match your needs
    2. You can efficiently read back useful information
    3. You can use dark theme
    What you can do with signing up
    9