1. 株式会社PALTEK
  2. TECHブログ
  3. 技術情報
  4. 【FPGAテストベンチ/検証ノウハウ】テストベンチTEXTIOの使い方 (VHDL編)

TECHブログ

【FPGAテストベンチ/検証ノウハウ】テストベンチTEXTIOの使い方 (VHDL編)

【FPGAテストベンチ/検証ノウハウ】テストベンチTEXTIOの使い方 (VHDL編)

今回はTEXTIOを使用してテストベンチについて説明します。
VHDLではTEXTIOは少々使いにくいところもありますが、工夫次第では便利に使用することが可能です。それでは始めましょう。

目次

ライブラリの追加

VHDLでTEXTIOを使うためにはライブラリを登録する必要があります。
下の2つを登録します。

use ieee.std_logic_textio.all ;
use std.textio.all ;

入出力ファイルの登録

ここでは上位からTEXTIOに使用するファイルを選択できるようにentity部でgeneric宣言にてファイルを登録しています。(下線部は任意の名前でOKです)

entity tb_textio_vhdl is
    generic(
        infile1  : string := "textio_in.txt" ;
        outfile1 : string := "textio_out.txt" 
    ) ;
    port(
    ︙


architecture宣言後にファイルを使用するためのfile宣言を行います。
in~とout~以降はentity部で宣言した名前と合わせましょう。

architecture tb_textio_vhdl of tb_textio_vhdl is
    file    indata1  : text is in infile1 ;
    file    outdata1 : text is out outfile1 ;

入力ファイルのサンプル

下記が入力テキストファイルのサンプルです。

-TIME R/W ADR DATA MASK
1100 R F1000334 0000000C FF0F0000
 1130 W F1000334 00000000
 1160 R F1000334 00000000 FFFFFFF7
 2360 R F1000334 00000000 FF0F0000
 2390 R F1000338 00000000 FF0F0000
 2420 R F10000C0 00000000 00000000
 2450 W F10000F0 FFFFFFFF
 2480 R F10000F0 00000000 FFFFFFF0
end


先頭1文字 コメント用 /実データの切り替え用
TEXTIOでは厳密に文字列を読み取ってしまうために、コメントなどを入れることができず何のテストベンチだったかな?と思う時があります。
それを解消するために1文字目を読み込んだ時点でコメントなのか実データなのかを判別させるため、実データではスペースそれ以外では文字列を入れています。

実データの2個目以降

  • ・実行時間(このCLK数後に実行)
  • ・リードまたはライトの識別
  • ・アドレス
  • ・データ (リード時は期待値)
  • ・マスク (リードのみ。リード値とorしてデータと比較します)

出力ファイルのサンプル

下記が入力テキストファイルに対する出力テキストファイルです。

1100 F1000334 FF0F000C FF0F000C OK 
 1160 F1000334 FFFFFFF7 FFFFFFF7 OK 
 2360 F1000334 FF0F0000 FF0F0000 OK 
 2390 F1000338 FF0F0000 FF0F0000 OK 
 2420 F10000C0 00000000 00000000 OK 
 2480 F10000F0 FFFFFFF0 FFFFFFF0 OK 


リード結果を表示しており、下記の内容を表示しています。

  • ・実行時間
  • ・アドレス
  • ・リード期待値
  • ・実リードデータ
  • ・期待値とのOK/NG判定

TEXTIOコマンド

コマンドは下記があります。使用方法については後述します。

readline  1行読み込み
read      文字列読み込み
hread     文字列読み込み(HEX)

write     文字列書き込み
hwrite    文字列書き込み(HEX)
writeline 1行書き込み

実行サンプル

下記がTEXTIOを使った処理のサンプルです。

process(CLK)
    variable cycle_busy1     : boolean := false ;  --入力ファイルサイクル制御
    variable L               : line ;              --ライン宣言
    variable MARK1           : character := ' ' ;  --先頭文字識別用
    variable TIME            : integer range 0 to 2147483647 := 0 ;
    variable RW              : character := ' ' ;  --リード/ライト識別用
    variable ADR             : std_logic_vector(31 downto 0) ;
    variable DAT             : std_logic_vector(31 downto 0) ;
    variable MASK            : std_logic_vector(31 downto 0) ;
    variable EOL             : boolean := false ;  --入力ファイル終了識別用
    variable OUT_file_write  : boolean := true ;   --出力ファイル書き込み制御
    variable CHE1            : string(1 to 2) ;    --判定条件文字用

begin
    if (not EOL) then --ファイルの最後でなければ入力ファイルを読み込み
        LOOP1 :
        while cycle_busy1 = false loop --ファイル読み込みループ
            readline(indata1,L) ;      --file宣言した入力ファイルから1ライン読み込み
            read(L,MARK1) ;            --上で読み込んだ1ラインの1文字目を読み込み
            if MARK1 /= 'e' and MARK1 /= '-' then --1文字目がeか-でなくスペースなら実データ
                read(L,TIME) ;  --時間読み込み
                read(L,MARK1) ; --区切り読み込み(スペース)
                read(L,RW) ;    --リードライト識別読み込み
                read(L,MARK1) ; --区切り読み込み(スペース)
                hread(L,ADR) ;  --アドレスをHEXで読み込み
                read(L,MARK1) ; --区切り読み込み(スペース)
                hread(L,DAT) ;  --データをHEXで読み込み
                read(L,MARK1) ; --区切り読み込み(スペース)
                hread(L,MASK) ; --マスクをHEXで読み込み
                if TIME < CNT then  --時間が指定カウンタ値までは待ち
                    cycle_busy1 := false ;
                else
                    cycle_busy1 := true ;
                end if ;
            elsif MARK1 = '-' then  --1文字目が-の場合コメントと判定
                cycle_busy1 := cycle_busy1 ;
            elsif MARK1 = 'e' then  --1文字目がeの場合ファイルの最後と判定
                EOL := true ;
            end if ;
        end loop LOOP1 ;
    end if ;

    if RW = 'W' then
		【ライト処理】
		cycle_busy1 := false ;
    end if ;

    elsif RW = 'R' then
		【リード処理】

    -- データチェック
		if R_DAT = (DAT or MASK) then
			CHE1 := "OK" ;
			OUT_file_write := false ;
		else
			CHE1 := "NG" ;
			OUT_file_write := false ;
		end if ;
		cycle_busy1 := false ;
    end if ;


    if OUT_file_write = false then
            write(L,MARK1) ;
            write(L,TIME) ;
            write(L,MARK1) ;
            hwrite(L,ADRS) ;
            write(L,MARK1) ;
            hwrite(L,R_DAT) ;
            write(L,MARK1) ;
            hwrite(L,RDAT) ;
            write(L,MARK1) ;
            write(L,CHE1) ;
            write(L,MARK1) ;
            write(L,CHE2) ;
            writeline(outdata1,L) ;
            OUT_file_write := true ;
    end if ;
end process;
if CLK'event and CLK = '1' then if RW = 'W' then --リードライト判定がWの処理 ※【ライト処理】 cycle_busy1 := false ; --処理が終わったら読み込み処理に戻る end if ; elsif RW = 'R' then --リードライト判定がRの処理 ※【リード処理readdataを取得】 -- データチェック if readdata = (DAT or MASK) then -- リードデータと比較 CHE1 := "OK" ; -- 一致ならCHE1にOKを挿入 OUT_file_write := false ; -- ファイル書き込み処理に移行 else CHE1 := "NG" ; -- 不一致ならCHE1にNGを挿入 OUT_file_write := false ; -- ファイル書き込み処理に移行 end if ; cycle_busy1 := false ; end if ; if OUT_file_write = false then --ファイル書き込み処理 write(L,MARK1) ; --区切り書き込み(スペース) write(L,TIME) ; --実行時間書き込み write(L,MARK1) ; --区切り書き込み(スペース) hwrite(L,ADRS) ; --アドレス書き込み(HEX) write(L,MARK1) ; --区切り書き込み(スペース) hwrite(L,DAT) ; --リードデータ期待値書き込み (HEX) write(L,MARK1) ; --区切り書き込み(スペース) hwrite(L,RDAT) ; --実リードデータ書き込み (HEX) write(L,MARK1) ; --区切り書き込み(スペース) write(L,CHE1) ; --判定結果書き込み writeline(outdata1,L) ; --1ライン書き込み OUT_file_write := true ; --書き込み処理終了 end if ; end process;

以上です。

今回は、テストベンチTEXTIOの使い方(VHDL編)と題しまして、
ライブラリの追加、入出力ファイルの登録、入出力ファイルのサンプル、TEXTIOコマンド、実行サンプルについてお話しました。
最後までご覧いただきましてありがとうございました!

今回説明した内容などでのご質問がありましたら、下記よりお問い合わせください。

お問い合わせはこちら

 

 

 

 関連ブログ