1. 株式会社PALTEK
  2. TECHブログ
  3. 技術情報
  4. 【FPGAテストベンチ/検証ノウハウ】テストベンチTEXTIOの使い方 ~応用~ Vivado®ロジックアナライザーでキャプチャしたデータを利用する(VHDL編)

TECHブログ

【FPGAテストベンチ/検証ノウハウ】テストベンチTEXTIOの使い方 ~応用~ Vivado®ロジックアナライザーでキャプチャしたデータを利用する(VHDL編)

【FPGAテストベンチ/検証ノウハウ】テストベンチTEXTIOの使い方 ~応用~ Vivado®ロジックアナライザーでキャプチャしたデータを利用する(VHDL編)

皆さん、TEXTIOを使用してテストベンチを作成していますか?
使いこなしてくるともっと便利に活用したくなりますよね。
今回は応用として、Vivado®ロジックアナライザーでキャプチャしたデータを、VHDLで書かれたテストベンチから読み出してシミュレーションを行う方法を紹介します。

なお、テストベンチTEXTIOの使い方の基本編をご覧になりたい方は、以下のブログをご覧ください。

それでは、はじめましょう。

目次

 

掲載している内容は次の条件で動作確認を行っています。

・ソースはVHDL 1987文法にて記述
・AMD ザイリンクス社 Vivado® ML Edition 2020.2
・Siemens社 ModelSim® SE-64 2021.3 (VHDL 1987文法 オプションを選択)

出典 : ModelSim® SE-64 2021.3 Project Compiler Settings画面

実機の構成

基板上に次のようなCPUとFPGAの構成があったとします。
Vivado®ロジックアナライザーはCPUインタフェース部分につながっており、その部分のデータをキャプチャするものとします。

実機の構成

図1 実機の構成

テストベンチの構成

先ほどの実機構成をテストベンチで次のように構成したとします。
本来であればCPUのモデルもHDL等で記述してシミュレーションを行いますが、このモデルの代わりにVivado®ロジックアナライザーでキャプチャしたCSVデータを使用してFPGAにアクセスを行います。

テストベンチの構成

図2 テストベンチの構成


左右にスクロールしてご覧ください
信号名      [信号の方向 ] : FPGAから見た信号の意味
cpu_cs      [CPU → FPGA] : CPUからのチップセレクト信号 (Lowアクティブ)
cpu_add     [CPU → FPGA] : CPUからのアドレス信号 (26bit)
cpu_wr_enbn [CPU → FPGA] : CPUからの書き込み要求信号 (Lowアクティブ)
cpu_wr_data [CPU → FPGA] : CPUからの書き込みデータ (32bit)
cpu_rd_reqn [CPU → FPGA] : CPUからの読み出し要求信号 (Lowアクティブ)
cpu_rd_enbn [CPU ← FPGA] : CPUへの読み出しデータ有効信号 (Lowアクティブ)
cpu_rd_data [CPU ← FPGA] : CPUへの読み出しデータ (32bit)

Vivado®ロジックアナライザーの準備

Vivado®ロジックアナライザーのWaveformにキャプチャする信号をならべて基数を設定します(デフォルトはHEXになっています)。

今回キャプチャする信号は、次の内容です。

なお、Waveformに表示されている信号名は今回テストベンチでは使用しませんが、HDLでは文字の扱いに柔軟性がないため、表示は短くしておいた方が無難です。

信号名を右クリック → Name → Short

出典 : Vivado® ML Edition 2020.2 Hardware Manger画面

波形のキャプチャ

トリガー条件を設定し、テストベンチで使用する波形のキャプチャを実行します。
今回は1024クロック分をキャプチャしています。

キャプチャ波形は次のようになります。

・波形全体

はじめに書き込みアクセスがあり、そのあとに読み出しアクセスが続けて行われています。

出典 : Vivado® ML Edition 2020.2 Hardware Manger Dashboard画面

・はじめの書き込みと読み出し部分のアップ

出典 : Vivado® ML Edition 2020.2 Hardware Manger Dashboard画面

CSV形式での保存

希望する波形のキャプチャができましたら保存します。
File → Export → Export ILA Data を実行します。

出典 : Vivado® ML Edition 2020.2 Hardware Manger Dashboard画面


ダイアログで保存するILA・フォーマット・パスとファイル名を聞いてきますので設定します。今回はフォーマットを「CSV」に設定して保存します。

出典 : Vivado® ML Edition 2020.2 Hardware Manger Dashboard画面

CSV入力ファイルのサンプル

先ほど保存したCSVファイルの中身はこのようになっています。

見やすくするためにフィールド幅を変えて表示していますが、実際はデータとカンマの間にスペースは入っていません。

出典 : Vivado® ML Edition 2020.2 Export ILA Data File


左から3つのフィールドは次の内容になります。

  • 「Sample in Buffer」はキャプチャしたときの全体のクロック数です
  • 「Sample in Window」は画面分割キャプチャをしたときの分割内でのクロック数です
  • 「TRIGGER」は1の所がトリガーのかかった場所になります

左から4つ目以降のフィールドはキャプチャした信号になります。

実行サンプル

以下がTEXTIOを使ってCSVファイルのデータを読み出すテストベンチのサンプルになります。

左右にスクロールしてご覧ください
library ieee;
  use ieee.std_logic_1164.all;
  use ieee.std_logic_unsigned.all;
  use ieee.std_logic_textio.all;          -- ファイルを扱うためのライブラリ呼び出し
  use std.textio.all;                     -- ファイルを扱うためのライブラリ呼び出し

entity tb_textio_vhdl is
  generic (
    infile1     : string := "iladata.csv" -- 読み込むファイルのパスとファイル名
  );
  port (
    clk         : in  std_logic;
    rst         : in  std_logic;
    cpu_cs      : out std_logic;                      -- CPUからのチップセレクト
    cpu_add     : out std_logic_vector(25 downto 0);  -- CPUからのアドレス
    cpu_wr_enbn : out std_logic;                      -- CPUからの書き込み要求
    cpu_wr_data : out std_logic_vector(31 downto 0);  -- CPUからの書き込みデータ
    cpu_rd_reqn : out std_logic;                      -- CPUからの読み出し要求
    sim_rd_enbn : in  std_logic;                      -- CPUへの読み出しデータ有効
    sim_rd_data : in  std_logic_vector(31 downto 0)   -- CPUへの読み出しデータ
  );
end tb_textio_vhdl;

architecture rtl of tb_textio_vhdl is
  file    indata1       : text is in infile1;               -- VHDL 1987 Syntax
--  file    indata1       : text open read_mode is infile1; -- VHDL 1993 Syntax
--  signal  fread         : std_logic;                      -- VHDL 2002/2008 Syntax
  signal  mask_cnt      : std_logic_vector(1 downto 0);     -- 信号名・基数情報行を読み飛ばすためのカウンタ
  signal  sib           : integer range 0 to 66536;
  signal  add           : std_logic_vector(25 downto 0);
  signal  csn           : std_logic;
  signal  wren          : std_logic;
  signal  wrdt          : std_logic_vector(31 downto 0);
  signal  rreq          : std_logic;
  signal  rden          : std_logic;
  signal  rddt          : std_logic_vector(31 downto 0);
  signal  end_of_file   : std_logic;                        -- ファイルの読み込み終了フラグ
  signal  cpu_rd_enbn   : std_logic;                        -- CPUへの読み出しデータ有効
  signal  cpu_rd_data   : std_logic_vector(31 downto 0);    -- CPUへの読み出しデータ
  signal  d_sim_rd_enbn : std_logic;
  signal  match_rd_data : string(1 to 2) := "  ";           -- 実機動作とシミュレーションの差分確認フラグ

begin
  process(clk,rst)
--    file    indata1 : text;                         -- VHDL 2002/2008 Syntax
    variable L      : line;                           -- ライン宣言
    variable MARK1  : character := ',';               -- 区切り文字識別用
    variable v_sib  : integer range 0 to 66536 := 0;  -- Sample in Buffer (このテストベンチでは確認だけに使用します)
    variable v_siw  : integer range 0 to 66536 := 0;  -- Sample in Window (このテストベンチでは値は使用しません)
    variable v_trig : std_logic;                      -- TRIGGER (このテストベンチでは値は使用しません)
    variable v_add  : std_logic_vector(27 downto 0);  -- CPUからのアドレス
    variable v_csn  : std_logic;                      -- CPUからのチップセレクト
    variable v_wren : std_logic;                      -- CPUからの書き込みデータ有効
    variable v_wrdt : std_logic_vector(31 downto 0);  -- CPUからの書き込みデータ
    variable v_rreq : std_logic;                      -- CPUからの読み出し要求
    variable v_rden : std_logic;                      -- CPUへの読み出しデータ有効
    variable v_rddt : std_logic_vector(31 downto 0);  -- CPUへの読み出しデータ
  begin
    if (rst = '1') then
--      fread       <= '1';                           -- VHDL 2002/2008 Syntax
      mask_cnt    <= "00";
      end_of_file <= '0';
      sib         <= 0;
      add         <= (others => '0');
      csn         <= '1';
      wren        <= '1';
      wrdt        <= (others => '0');
      rreq        <= '1';
      rden        <= '1';
      rddt        <= (others => '0');
    elsif (CLK'event and CLK = '1') then
--      if (fread = '1') then                       -- VHDL 2002/2008 Syntax
--        file_open (indata1, infile1, READ_MODE);  -- VHDL 2002/2008 Syntax
--        fread <= '0';                             -- VHDL 2002/2008 Syntax
--      else                                        -- VHDL 2002/2008 Syntax
        if (end_of_file = '0') then                 -- ファイルの最後でなければ入力ファイルを読み込み
          if (not endfile(indata1)) then            -- 読み込みファイルが EOF = true でなければ実行
            readline(indata1,L) ;                   -- file宣言した入力ファイルから1ライン読み込み

            if (mask_cnt /= "11") then              -- csvファイルの最初の2行を読み飛ばす
              mask_cnt  <= mask_cnt + '1';
            else
              mask_cnt  <= mask_cnt;
            end if;

            if (mask_cnt = "11") then
              -- CSVファイルの信号並びに合わせる
              -- VIVADO ロジックアナライザーで基数をHEXに設定した場合には"hread"を使用する
              read (L,v_sib );    -- Sample in Bufferを読み込み
              read (L,MARK1 );    -- 区切り読み込み(カンマ)
              read (L,v_siw );    -- Sample in Windowを読み込み
              read (L,MARK1 );
              read (L,v_trig);    -- TRIGGERを読み込み
              read (L,MARK1 );
              hread(L,v_add );    -- アドレスをHEXで28bit読み込み
              read (L,MARK1 );
              hread(L,v_rddt);    -- 読み出しデータをHEXで32bit読み込み
              read (L,MARK1 );
              hread(L,v_wrdt);    -- 書き込みデータをHEXで32bit読み込み
              read (L,MARK1 );
              read (L,v_csn );    -- チップセレクトを読み込み
              read (L,MARK1 );
              read (L,v_rden);    -- 読み出しデータ有効を読み込み
              read (L,MARK1 );
              read (L,v_rreq);    -- 読み出し要求を読み込み
              read (L,MARK1 );
              read (L,v_wren);    -- 書き込みデータ有効を読み込み

              -- ファイルから読み込んだ値を各信号に代入
              sib   <= v_sib;
              add   <= v_add(25 downto 0);  -- 不要な上位2bitを削除
              csn   <= v_csn;
              wren  <= v_wren;
              wrdt  <= v_wrdt;
              rreq  <= v_rreq;
              rden  <= v_rden;
              rddt  <= v_rddt;
            end if;
          else
--              file_close (indata1);   -- VHDL 2002/2008 Syntax
              end_of_file <= '1';       -- ファイルの読み出し終了
          end if;
        end if;
--      end if;                         -- VHDL 2002/2008 Syntax
    end if;
  end process;

  cpu_add     <= add;
  cpu_cs      <= csn;
  cpu_wr_enbn <= wren;
  cpu_wr_data <= wrdt;
  cpu_rd_reqn <= rreq;
  cpu_rd_enbn <= rden;
  cpu_rd_data <= rddt;

  -- 実機動作とシミュレーションを比較
  process(CLK) begin
    if (CLK'event and CLK = '1') then
        d_sim_rd_enbn <= sim_rd_enbn;
    end if;
  end process;

  match_rd_data <=  "- " when ((d_sim_rd_enbn or rreq) = '1') else
                    "OK" when (sim_rd_data = cpu_rd_data)     else
                    "NG";

end rtl;

シミュレーション実行結果

シミュレーションを実行し、CPUモデルから見た(CVSファイルを読み出した)結果は次のようになります。
※波形の色は筆者が一部変更しています。
※sib 信号は基数をunsignedに設定しています。

・波形全体

出典 : ModelSim® SE-64 2021.3 Wave画面

・はじめの書き込みと読み出し部分のアップ

出典 : ModelSim® SE-64 2021.3 Wave画面

Vivado®ロジックアナライザーでキャプチャした波形と同じようになっていることがわかるかと思います。

おわりに

今回はバスの動きをすべてキャプチャして再現させましたが、例えばバーストで流れてくるデータだけをキャプチャしてそれをシミュレーションで利用するなど、いろいろなことに応用できるかと思います。

最後までご覧いただきましてありがとうございました。


お問い合わせはこちら

このブログのシリーズ

関連ブログ