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

TECHブログ

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

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

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

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

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

目次

 

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

・AMD ザイリンクス社 Vivado® ML Edition 2020.2
・Siemens社 ModelSim® SE-64 2021.3 (Verilog 1995文法 オプションを選択)
 ※Verilog 2001/System Verilog でも実行可

実機の構成

基板上に次のような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

波形のキャプチャ

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

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

・波形全体

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

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

CSV形式での保存

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


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

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

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

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


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

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

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

実行サンプル

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

左右にスクロールしてご覧ください
module tb_textio_verilog #(
  parameter  infile1  ="iladata.csv"  // 読み込むファイルのパスとファイル名
)(
  input   wire          clk,
  input   wire          rst,
  output  wire          cpu_cs,       // CPUからのチップセレクト
  output  wire  [25:0]  cpu_add,      // CPUからのアドレス
  output  wire          cpu_wr_enbn,  // CPUからの書き込み要求
  output  wire  [31:0]  cpu_wr_data,  // CPUからの書き込みデータ
  output  wire          cpu_rd_reqn,  // CPUからの読み出し要求
  input   wire          sim_rd_enbn,  // CPUへの読み出しデータ有効
  input   wire  [31:0]  sim_rd_data   // CPUへの読み出しデータ
);

  integer             file_in;        // ファイルから読み出した一行分のテキストの一時保存場所
  reg     [1:0]       mask_cnt;       // タイトル・信号名行を読み飛ばすためのカウンタ
  integer             sib;            // Sample in Buffer (このテストベンチでは確認だけに使用します)
  integer             siw;            // Sample in Window (このテストベンチで値は使いません)
  reg                 trig;           // TRIGGER (このテストベンチで値は使いません)
  reg     [8*1024:1]  note;           // 信号名・基数情報行を仮読み用 (このテストベンチで値は使いません)
  reg     [25:0]      add;            // CPUからのアドレス
  reg                 csn;            // CPUからのチップセレクト
  reg                 wren;           // CPUからの書き込みデータ有効
  reg     [31:0]      wrdt;           // CPUからの書き込みデータ
  reg                 rreq;           // CPUからの読み出し要求
  reg                 rden;           // CPUへの読み出しデータ有効
  reg     [31:0]      rddt;           // CPUへの読み出しデータ
  reg                 end_of_file;    // ファイルの読み込み終了フラグ
  wire                cpu_rd_enbn;    // CPUへの読み出しデータ有効
  wire    [31:0]      cpu_rd_data;    // CPUへの読み出しデータ
  reg                 d_sim_rd_enbn;
  wire    [2*8:1]     match_rd_data;  // 実機動作とシミュレーションの差分確認フラグ

initial begin
    file_in   = $fopen(infile1, "r");
end

always @(posedge clk or posedge rst) begin
  if (rst == 1'b1) begin
    mask_cnt    <= 2'h0;
    end_of_file <= 1'b0;
    sib         <= 0;
    siw         <= 0;
    trig        <= 0;
    add         <= 26'h000_0000;
    csn         <= 1'b1;
    wren        <= 1'b1;
    wrdt        <= 32'h0000_0000;
    rreq        <= 1'b1;
    rden        <= 1'b1;
    rddt        <= 32'h0000_0000;
  end else begin
    if (end_of_file == 1'b0) begin      // ファイルの読み出しが終わったらこれ以降ファイルにアクセスさせない
      if ($feof(file_in) != 1) begin    // 読み込みファイルが EOF = 1 でなければ実行
        if (mask_cnt < 2'h2) begin
          $fgets (note, file_in);       // 信号名・基数情報行の行を仮読み 
          mask_cnt <= mask_cnt + 2'h1;  // csvファイルの最初の2行を読み飛ばす
        end else begin
          $fscanf(file_in, "%d,%d,%d,%h,%h,%h,%h,%h,%h,%h\n",     // VIVADO ロジックアナライザーで設定した基数に合わせる
                  sib,siw,trig,add,rddt,wrdt,csn,rden,rreq,wren); // CSVファイルの信号並びに合わせる
          mask_cnt <= mask_cnt;
        end
      end else begin
        $fclose(file_in);     // EOFでファイルクローズ
        end_of_file <= 1'b1;  // ファイルの読み出し終了
      end
    end
  end
end

assign  cpu_add[25:0]     = add[25:0];
assign  cpu_cs            = csn;
assign  cpu_wr_enbn       = wren;
assign  cpu_wr_data[31:0] = wrdt[31:0];
assign  cpu_rd_reqn       = rreq;
assign  cpu_rd_enbn       = rden;
assign  cpu_rd_data[31:0] = rddt[31:0];

// 実機動作とシミュレーションを比較
always @(posedge clk) begin
  d_sim_rd_enbn <= sim_rd_enbn;
end

assign  match_rd_data = ((d_sim_rd_enbn | rreq)  == 1'b1)        ? "- " :
                        (sim_rd_data[31:0] == cpu_rd_data[31:0]) ? "OK" : "NG";

endmodule

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

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

・波形全体

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

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

おわりに

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

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


お問い合わせはこちら

このブログのシリーズ

関連ブログ