ファイルの読み書き

[] [] []


テストベンチで、入力を予め用意したファイルから読み込んだり、出力をファイルに書き出して、後で期待値ファイルと比較する、という手もよく使う。

配列(RAM相当)HEX値を読み込むだけならば $readmemh を使う。

) テキストファイルから配列memHEX値を読み込む

reg[15:0] mem[0:256];

initial begin

  $readmemh("dat_in.txt",mem);

end

ファイルは「@先頭アドレス 値 値 ...」で16進数で書く。スペースやタブや改行が区切り。コメント行はVerilogと同じ。値を書かなかったアドレスは不定(x)のままになる。

/* dat_in.txt */

1234

abcd

bcde

...

//アドレスを省略すると

//0番地から始まる

/* dat_in.txt */

@00 1234

@01 abcd

@02 bcde

...

//アドレスを

//全部書いても可

/* dat_in.txt */

@10 1234 abcd

@ff 5678

//10,11,ff番地と

//飛び飛びでも可

◇◇

任意のフォーマットで読み込むには $fscanfを使う。

) テキストファイルからフォーマットに従って読み込む

integer fd; // file descriptor

initial begin

  // ファイルを開く(存在しないとfd=0になる)

  fd = $fopen("dat_in.txt","r");

  if(fd===0) $finish;

  // ファイルから1行ずつフォーマットに従って読み込む

  // 1行目はヘッダ(a=13,b=25)

  num = $fscanf(fd,"a=%d,b=%d",a,b);

  // 2行目からはデータ

  while($feof(fd)===0) begin

     num = $fscanf(fd,"%d",dat);

     ...

  end

  $fclose(fd);

end

◇◇◇

書き出すには $fdisplay,$fwriteを使う。違いは、$fdisplayは改行つき、$fwriteは改行なし。

) テキストファイルへフォーマットに従って書き出す

integer fd; // file descriptor

reg[7:0] mem[0:N-1];

initial begin

  // ファイルを開く(空ファイルが作られる)

  fd = $fopen("dump.txt","w");

  // ファイルへ8バイト/行で書き出す

  for(i=0; i<=N-1; i=i+1) begin

     if(i%8===0) $fwrite(fd,"%0d: ",i);

     $fwrite(fd,"%h",mem[i]);

     if(i%8==7 | i==N-1) $fwrite(fd,"\n");

  end

  $fclose(fd);

end

何かの定数表を作るときも、CでなくVerilogを使った方が簡単なこともある。

) IEEE754フォーマットのsinの表を作る

initial begin

  fd = $fopen("sin.txt","w");

  for(int k=0; k<N; k++) begin

     $fdisplay(fd,"%h",$shortrealtobits($sin(PI*k/N));

  end

  $fclose(fd);

end

◇◇◇◇

バイナリファイルへ書き出すには $fopen( ,"wb")で開いて、$fwrite( ,"%c", )を使う。

) バイナリファイルへ1バイトずつ書き出す

integer fd; // file descriptor

reg[7:0] mem[0:N-1];

initial begin

  // ファイルを開く(空ファイルが作られる)

  fd = $fopen("dat_out.bin","wb");

  // 1バイトずつ書き出す

  for(i=0; i<=N-1; i=i+1) begin

     $fwrite(fd,"%c",mem[i]);

  end

  $fclose(fd);

end

◇◇◇◇◇

バイナリファイルから読み込むには $fopen( ,"rb")で開いて、$freadを使う。

) バイナリファイルから1バイトずつ読み込む

integer fd; // file descriptor

reg[7:0] dat;

initial begin

  fd = $fopen("dat_in.bin","rb");

  // 1バイトずつ読み込む,最後にEOFが読まれる

  while($feof(fd)===0) begin

     num = $fread(dat,fd);

     ...

  end

  $fclose(fd);

end

) バイナリファイルからバイト数を指定して読み込む

integer fd; // file descriptor

reg[7:0] head[0:M-1];

reg[7:0] data[0:N-1];

initial begin

  // ファイルを開く(存在しないとfd=0になる)

  fd = $fopen("dat_in.bin","rb");

  if(fd===0) $finish;

  // 先頭からMバイト読み込む

  num = $fread(head,fd,0,M);

  // 続きからNバイト読み込む

  num = $fread(data,fd,0,N);

  ...

  $fclose(fd);

end


[] [] []