01signal.com

シンプルな data acquisition と Xillybus

概要

Xillybusの最も一般的な使用シナリオは data acquisitionです。このページでは、 FPGA から hostへの data の送信を開始する方法を示します。

FPGA内の Xillybus との相互作用の詳細については、 Xillybus FPGA designer's guideを参照してください。

アプリケーションの data rateが高い場合は、 Linuxまたは WindowsのGetting Started guide の第 5 章でこれに関するガイドラインを読むこともお勧めします。

hostの側面

Xillybus がどのように機能するかを理解するには、コンピューター側から始めるのが最も簡単です。 このコマンドを使用して、ディスク上のファイルに data acquisition を実行できます。

$ cat /dev/xillybus_read_32 > capture-file.dat

「cat」は、ファイルからすべての data を読み取り、この data を standard outputに書き込む標準の Linux コマンドです。この例では、入力は通常のファイルではなく、 device fileです。この入力は、 FPGAから到着する data stream で構成されます。 standard outputの redirection があるので、この data はディスク上のファイルに書き込まれます。

これは人工的な例ではありません: 一部の使用シナリオでは、これが実際に Xillybus を data acquisitionに使用する正しい方法です。 dataを一定量手に入れるには「dd」を使ったほうがいいかもしれません。多くの場合、専用のコンピューター プログラムを使用して、 device fileから data を読み取ります。各アプリケーションには、 dataを使用する独自の推奨方法があります。

したがって、どのプログラミング言語を好むか、または Linux と Windowsのどちらを使用するかは問題ではありません。 FPGA から data を受信するコンピュータ ソフトウェアは、「cat」と同じことを行うだけで済みます。 ファイルを開き、そこから読み取ります。 file I/Oの標準的なプログラミング手法を紹介する別のページがあります。 Xillybus でのプログラミング手法に関するさらに詳細な情報は、 Linux および Windowsのプログラミング ガイドに記載されています。

data acquisitionのための logic

では、 FPGAで何が起こるか見てみましょう。 Xillybus IP core と application logic は FIFOを介して対話します。 application logic は data を FIFOに書き込み、 Xillybus はこの data が hostに到達することを確認します。この概念に慣れていない場合は、 FIFOs がどのように機能するかを説明する別のページがあります。

Xillybusの demo bundle には、 xillydemo.vという名前のファイルが含まれています。これは、 IP coreとインターフェイスする Verilog コードです。 demo bundleには VHDL ファイルもあります。 xillydemo.vhd.ただし、以下の例は Verilogのものです。

Xillybus IP coreの instantiation は xillydemo.vで行われます。 (または xillydemo.vhd)。これらは、上記の「cat」コマンドを使用した data acquisition の例に関連する部分です (他の部分はスキップされます)。

// Wires related to /dev/xillybus_read_32
   wire        user_r_read_32_rden;
   wire        user_r_read_32_empty;
   wire [31:0] user_r_read_32_data;
   wire        user_r_read_32_eof;
   wire        user_r_read_32_open;

[ ... ]

   xillybus xillybus_ins (
[ ... ]
			  // Ports related to /dev/xillybus_read_32
			  // FPGA to CPU signals:
			  .user_r_read_32_rden(user_r_read_32_rden),
			  .user_r_read_32_empty(user_r_read_32_empty),
			  .user_r_read_32_data(user_r_read_32_data),
			  .user_r_read_32_eof(user_r_read_32_eof),
			  .user_r_read_32_open(user_r_read_32_open),
[ ... ]
			  .bus_clk(bus_clk),
[ ... ]
			  );

IP coreの ports の意味は、Xillybusの logic APIガイドで詳しく説明されています。

xillydemo.vには FIFO の instantiation があります。この FIFO は single-clock FIFOであり、元の Verilog コードで実証されている loopback に適しています。 data acquisition アプリケーションの場合、 data acquisition logic は通常、独自の clockに依存しているため、 dual-clock FIFO の方が適しています。

したがって、次のように xillydemo.v を data acquisition を実行する module に変更できます。 single-clock FIFO の instantiation を削除します ( fifo_32x512と呼ばれます)。代わりにこれを挿入します:

assign user_r_read_32_eof = 0;

   dualclock_fifo_32 fifo_32
     (
      .rd_clk(bus_clk),

      .rst(!user_r_read_32_open),
      .rd_en(user_r_read_32_rden),
      .dout(user_r_read_32_data),
      .empty(user_r_read_32_empty)

      .wr_clk(capture_clk),

      .wr_en(capture_en),
      .din(capture_data),
      .full(capture_full)
      );

dual-clock FIFO

dualclock_fifo_32 は標準の dual-clock FIFOです。 FPGAの開発ソフトウェアで IP として作成する必要があります。この FIFO の深さは 512 elements 以上である必要があります。 FPGA ソフトウェアの違いにより、 ports の名前は上記と異なる場合があります。それにもかかわらず、 FIFOの signalsを接続する方法を推測するのは簡単です。

FIFOsにまだ慣れていない方のために、もう一度 FIFOsを紹介するページがあります。

FIFOの ports のいくつかは、 Xillybusの IP coreに直接接続されています。 @rd_clk、 @rd_en、 @dout 、 @empty。これらの接続は、 demo bundleとまったく同じであることに注意してください。 IP core は、これら 4 つの signals を使用して、 FIFOから data を引き出します。これは常に、これらの ports を IP coreに接続する正しい方法です。

@rd_clk は @bus_clkに接続されていることに注意してください。この signal は、 Xillybusの IP coreから派生したものです。つまり、 IP core は、 FIFOのいずれかの側で使用される clock を決定します。

@rstに関しては、 !user_r_read_32_openに接続されていることに注意してください。 @user_r_read_32_open は、関連する device file が hostで開いている場合にのみハイになります。その結果、ファイルが開かれていないときに FIFO がリセットされます。したがって、 host が device fileを開くと、 FIFO は空になります。 以前のセッションから FIFOのストレージに残り物があった場合、それらは device file が閉じられたときに削除されました。

この動作は、 dataのソースから通常期待されるものです。ただし、 device file を閉じたときに FIFO に data を保持させたい場合は、別のものを @rstに接続します。または、 @rst を低く保持することもできます。

この例と demo bundleでは、 @user_r_read_32_eof がゼロであることに注意してください。この signal を使用して、 end-of-file を hostに送信できます。これについては、 APIのガイドを参照してください。

application logicとのインターフェース

data acquisition アプリケーションでは、 hostへの送信用に data を生成するある種の application logic が常に存在します。この部分はアプリケーションごとに異なるため、この説明には関係ありません。この data を hostに送信することに焦点を当てます。

この部分は驚くほど簡単です。 application logic は、この data を FIFOに書き込みます。 FIFO に書き込まれた data は、連続した data streamとして host 上のコンピューター プログラムに到達します。

したがって、 application logic は、 FIFOへの書き込みに標準的な規則を使用します。上記の例では、これは @capture_clk、 @capture_en、 @capture_data 、および @capture_fullで示されています。この logic は、 FIFOに正しく書き込むために、 data を @capture_data に入れ、 @capture_en を制御するだけで済みます。 application logic は、 FIFOへの書き込みに独自の clock を使用することに注意してください。

data flow

これは、 host上の application logic から user application program までの data flow を示す単純化されたブロック図です。

Simplified data flow diagram for data acquisition with Xillybus

このブロック図では、次の 2 つの技術的な詳細が省略されていることに注意してください。 PCIe block と kernel driver は、ユーザーの data flowに対する認識とは無関係であるため、表示されていません。 Xillybus を使用する正しい方法は、これらの詳細を忘れて、 application logic と application softwareに集中することです。

data を packetsに編成する必要はありません。 application logic とコンピュータ間の通信チャネルは continuous streamです。 IP core と driver は、 data flow が他の stream protocolsのように動作することを保証します。たとえば、 Linuxのプログラム間での pipes です。同様の動作をする別のプロトコルは TCP/IPです。つまり、 data が FIFOにどれだけ書き込まれても問題ありません。この data は、まもなく host上の user application program に到達します。

data を packets に編成し、 IP coreの DMA buffers をこれらの packetsのサイズに適合させるのはよくある間違いです。これを行う利点はありません。 data が固定サイズの packets で送信された場合でも、 IP core をこのサイズに合わせる必要はありません。

しかし、 FIFO がいっぱいになったらどうしますか?

FIFO に関する基本的なルールの 1 つは次のとおりです。 @full port が高い場合、 @wr_en は低くなければなりません。簡単に言えば: 完全な FIFOに書き込まないでください。それで、それが起こったらどうしますか?この状況を処理すると、 application logic はかなり複雑になります。

簡単に言えば、 FIFO がいっぱいになることはありません。 通常の操作条件下では、これはアクティブに防止されます。 IP core は FIFO から data を読み取り、この data を hostの RAMにコピーします。これは、 FIFO がいっぱいになるのを防ぐのに十分な速さで発生します。通常、 FIFO は 512 data elementsより深くする必要はありません。

ただし、 application logic から FIFO への書き込みが速すぎると、 FIFO がいっぱいになることがあります。言い換えれば、 application logicの平均 data bandwidth が IP coreの制限 ( IP coreの各タイプで宣伝されている) を超えた場合、 IP core は FIFOから十分に速く data を読み取ることができなくなります。

もう 1 つの可能性は、 user application software (上記の例の「cat」など) が device fileから data を十分に速く読み取れないことです。その結果、 host RAM buffer がいっぱいになり、これも IP core が FIFO から読み取ることができなくなります ( IP core には data を書き込む場所がないため)。その結果、 overflow が発生します。これは、 user application software の書き方が悪いために起こります。別の考えられる理由として、オペレーティング システムに関連するものがあります。これについては、以下で詳しく説明します。

host 上の RAM buffer のサイズは、 Xillybus IP Coreによって異なります。たとえば、このサイズは xillybus_read_32 および xillybus_write_32 ( demo bundleの一部である IP core 内) の場合は 4 MBytes です。 IP Core Factory を使用すると、非常に大きな buffersを要求するカスタム IP cores を作成できます。

結論は: overflow を防止するには、 IP coreの正しいパラメーターを選択する必要があります。 何よりもまず、この IP core は data rateを処理できる必要があります。それに加えて、 host RAM buffer は十分な大きさでなければなりません。これにより、 user application program が device fileから data を読み取らない場合でも、 data flow が継続できることが保証されます。

それでも FIFO がいっぱいになる場合、一般的な理由は system designのミスです。 overflow の一般的な理由は、 data rateを処理するコンピューターの能力を過大評価することです。

特に、 data がディスク上のファイルに書き込まれる場合 (上記の「cat」コマンドのように)、最大の data rate は、考えられているよりも遅くなる可能性があります。その理由は、オペレーティング システムに大きな disk cache (おそらく多くの Gigabytes) があることが多いためです。ディスクの data rate が disk cacheよりも小さい data の量で測定される場合、結果は楽観的すぎます。 オペレーティング システムは、これが実際に発生する前に、 data のディスクへの書き込みが完了したふりをします。実際には、 data は cacheにしか到達せず、ディスクへの実際の書き込みは後で行われます。この間違いは、 data を大量に扱った場合にのみ明らかになります。

CPUの剥奪

残念ながら、 overflowには避けられない可能性があります。 オペレーティング システム (Linux または Windows) は、 user-space process から CPU を無期限に奪うことができます。つまり、 data を読み取るコンピューター プログラムが、突然一定期間動作を停止した後、通常の動作を再開する可能性があります。この期間に制限はありません。 non-real-time operating system は、このように processes をランダムに一時停止することができます。

それでも、 data acquisition はこれらのオペレーティング システムで引き続き使用できます。これは主に、 CPU の長期間の剥奪が一般的に悪い特性と見なされるためです。したがって、これらの一時停止は通常短いです。

これらの一時停止中、 IP core は host 上の RAM buffer を満たし続けます ( DMAのおかげで、 processorの介入は必要ありません)。コンピュータ プログラムが CPU を取り戻すと、蓄積されたすべての data をすばやく消費できます。通常、 10 ms の一時停止を補う RAM buffer で十分です。ただし、 IP Core Factoryでカスタム IP core を作成する場合は、大幅に大きい buffer を要求することができます。

とはいえ、一時停止が長すぎる可能性はまだあります。その結果、 RAM buffer がいっぱいになり、その結果、 FPGA 上の FIFO がいっぱいになります。この overflow の結果、 data が失われます。これは決して起こらないはずであり、おそらく決して起こらないでしょう。しかし、そうなったらどうしますか?

overflowの検出

推奨される解決策は、 FIFO がいっぱいになった場合に data stream を終了することです。 logic は、連続する dataの最後の要素の直後に、 EOF (end-of-file) を host に送信します。上記のように、 host が "cat" コマンドで data を消費した場合に何が起こるかを考えてみましょう。

$ cat /dev/xillybus_read_32 > capture-file.dat

通常、このコマンドは CTRL-Cで停止されるまで続行されます。ただし、 FPGAで FIFO がいっぱいになると、通常のファイルのコピーが終了した場合と同様に、このコマンドは正常に終了します。出力ファイルには、 FIFO がいっぱいになる前に収集されたすべての data が含まれます。

この方法を要約すると、次のようになります。 capture-file.dat に書き込まれるすべての data は、エラーがなく、連続していることが保証されています。 CPU の剥奪のために data acquisition システムが連続性を維持できない場合、結果として出力ファイルが短くなります。しかし、ファイルの内容は信頼できます。

このソリューションを実装するには、 dualclock_fifo_32の instantiation を次のものに置き換えます。

eof_fifo fifo_32
     (
      .rd_clk(bus_clk),

      .rst(!user_r_read_32_open),
      .rd_en(user_r_read_32_rden),
      .dout(user_r_read_32_data),
      .empty(user_r_read_32_empty)

      .wr_clk(capture_clk),

      .wr_en(capture_en),
      .din(capture_data),
      .full(),
      .eof(user_r_read_32_eof)
      );

eof_fifo の定義は別のページに記載されています。

@user_r_read_32_eof はこの FIFOの @eof portに接続されていることに注意してください。これは、必要に応じて logic が EOF を host に送信する方法です。また、この FIFOの @full portには何も接続されていないことにも注意してください。 この信号を監視する必要はもうありません。 FIFO がいっぱいになった場合、それに対してできることはあまりありません。 EOF メカニズムは、有効なデータがすべて消費された後に host がデータ フローを再開することを保証します。

Data playback

反対方向はどうですか?このようなものはどうですか?

$ cat playback-data.dat > /dev/xillybus_write_32

これは同じ原理で機能します: 「cat」コマンドは、ディスク上のファイルから読み取り、 data を device fileに書き込みます。 FPGAでは、 IP core がこの data を FIFOに書き込みます。 application logic は、 FIFOから data を読み取ります。考え方は同じですが、逆方向のみです。

これは、 host 上の user application program から application logicまでの data flow を示す簡略化されたブロック図です。

Simplified data flow diagram for data playback with Xillybus

data acquisitionと同様に、 dataの損失のリスクはありません。 IP core は、いっぱいになると FIFO に書き込みません。その結果、 hostの RAM 内の buffer も満杯になる可能性があります。これが発生すると、 host 上の user application program は、 application logic が FIFOから十分な data を読み取るまで (スリープによって) 待機します。

data acquisition とのもう 1 つの類似点は、 user application program が data に十分な速さで書き込みを続ける限り、 FIFO が空になることはないということです。これを保証するために、同じ考慮事項が関連しています。 IP coreの仕様と user application program は、必要な data rateをサポートする必要があります。

これらの条件が満たされると、この data が必要なときに、 application logic は FIFO から data を消費できます。 underflow は決して起こらないはずです。

Asynchronous streams 対 Synchronous streams

このトピックは直接関係ありませんが、簡単に説明する価値があります。

data acquisition アプリケーションの主な目標は、継続的な data flowを維持することです。したがって、 IP core は data を FIFO から hostの RAM buffer にできるだけ早く移動します。 host 上の user application program が特定の瞬間に data を要求しているかどうかは問題ではありません ( read() への関数呼び出しなどにより): data flow は、 device file が開いていて、 FIFOに data がある限り継続します。

これは、 host が FPGA から data flow を制御する方法がないことを意味します ( device fileの開閉、またはアプリケーション固有のソリューションに頼る場合を除く)。ただし、ほとんどの実際の data acquisition アプリケーションでは、 data flowを制御する必要はありません。 device fileを開いた結果、 data flow が起動するのは問題ありません。 data の各要素が FIFOから読み取られた正確なタイミングは重要ではありません。

このように動作する device file は、 asynchronous stream ( Xillybusの用語で) と呼ばれます。

ただし、他のアプリケーションでは、 data がいつ収集されたかが重要です。たとえば、 FPGA 上の application logic は、 FIFOから data の代わりに status register のコンテンツを送信する場合があります。これは、 xillybus_mem_8という名前の device file を使用した demo bundle で実証されています。この場合、 data が FPGAでいつ収集されるかを制御することが非常に重要です。 host は、現在のステータスに関する情報を取得するために device file から読み取ります。過去の未知の時点でのステータスではありません。

Xillybus には、この種のアプリケーション用の synchronous streams があります。 IP core は常に、 FPGAからできるだけ少ない data を収集します。言い換えると、 IP core は、 host上の read() (または同様のもの) への関数呼び出しに応答してのみ data を収集します。したがって、 data が FPGAから収集される場合、 host が制御します。

synchronous streams の欠点は、 data flowの一時停止です。これらの一時停止の主な問題は、 data flow が一時的に停止したときに、 FPGA 上の FIFO がいっぱいになる可能性があることです。これらの一時停止は data flowの効率も低下させるため、最大 data rate は低くなります。ただし、これらの 2 つの欠点は、 data acquisition アプリケーションにのみ関連します。このようなアプリケーションでは、とにかく asynchronous stream を使用する必要があります。

逆方向の device files に関しては、 asynchronous streams と synchronous streamsにも違いがあります。この方向では、違いは write() 関数呼び出しの戻りにあります。 asynchronous streamsでは、 data が RAM bufferに書き込まれるとすぐに、 write() が戻ります。そのため、ほとんどの場合、 write() はまったくスリープしません。一方、 synchronous streamsでは、 write() は data が FPGAに配信されるまで待機します。これは、通信チャネルを使用してコマンドを送信する場合に重要です。しかし、繰り返しますが、これは data acquisition アプリケーションにとっては悪いことです。

demo bundleでは、 /dev/xillybus_mem_8 のみが synchronous streamです。他の 4 つの device files は asynchronous streamsです。

IP Core Factoryでは、 synchronous stream または asynchronous streams の選択はアプリケーションの選択に依存します (「use」の場合は drop-down menu )。たとえば、「Data acquisition / playback」を選択すると、ツールは asynchronous streamsを生成します。 「Command and status」を選択すると、 synchronous streamが手に入ります。 「Autoset internals」をオフにすることで、これを手動で選択することもできます。

asynchronous streams および synchronous streamsの詳細については、 programming guide for Linux (またはprogramming guide for Windows ) のセクション 2 を参照してください。 IP Core Factoryについては、 guide to defining a custom Xillybus IP coreを参照してください。

概要

シンプルでありながら実際に機能する data acquisition システムは、 Xillybusを使用して簡単かつ迅速に作成できます。 application software は、標準の Linux コマンド ("cat") を使用することに要約されます。 FPGA側では、 Xillybusの IP core とのやり取りは、 data を FIFOに書き込むだけです。

Xillybus で収集された data は、エラーがなく、連続していることが保証されています。ただし、オペレーティング システムの性質上、 overflow が発生しないことを保証する方法はありません。これは避けられないため、最適なアプローチは、 overflow が発生した場合の検出を保証することです。 Xillybus は、 EOF を hostに送信することにより、この目的のための単純なメカニズムを提供します。

このページは英語から自動翻訳されています。 不明な点は元のページを参照してください。
Copyright © 2021-2024. All rights reserved. (6f913017)