01signal.com

フロー制御:MGT で使うための方法とプロトコル

このページは、マルチギガビット・トランシーバ(MGT)を紹介する一連のページの 8 ページ目であり、最後のページです。

はじめに

フロー制御(flow control)は、さまざまな種類のデータリンクでよく使われるメカニズムです。このメカニズムの目的は、送信されるデータ量が受信側で処理できる量を超えてしまう状況を防ぐことです。

MGT 関連のプロトコルは、この機能に対してさまざまなレベルのサポートを提供します。例えば、PCIe プロトコルを実装するロジックは、受信側のバッファが満杯の場合、送信のためにパケットを受け取ることは決してありません。PCIe プロトコルを使うアプリケーションロジック(application logic)は、これに関連して何かを実装する必要はありません。むしろ、アプリケーションロジックと PCIe プロトコルのロジックとの間のインターフェースにより、プロトコル側が新しいデータを一時的に受け取り拒否できるようになっています(例えば、AXI-S の VALID や READY などのポートを利用します)。同様に、アプリケーションロジックも、相手側から到着するデータを一時的に受け取り拒否できます。そうすることで、アプリケーションロジックはオーバーフロー(overflow)から身を守ります。

MGT 自身のエラスティックバッファ(elastic buffer)内のオーバーフローを防ぐためのメカニズムと、フロー制御を混同しないことが重要です。フロー制御は、MGT 自身のバッファに関するページで述べたスキップシンボルとは無関係です。むしろフロー制御は、アプリケーションロジック側のバッファを保護するものです。また、MGT を共有リソースとして使うデータチャネルが複数あることがよくあるため、フロー制御はそのような各チャネルに対して別々に、そして独立して実施されます。

一般的に言えば、コンピュータとの通信を定義するプロトコルは、フロー制御のメカニズムを自ら処理します。アプリケーションロジックは、他の多くのタイプのロジックブロックと同じように、単純なハンドシェイクポートを使ってプロトコルのロジックとやり取りするだけでよいのです。PCIe に加えて、SuperSpeed USB と SATA もフロー制御を自ら処理します。

残念ながら、FPGA 間の通信用プロトコルは、通常このレベルのフロー制御をサポートしていません。フロー制御を完全に処理する唯一のプロトコルは、Xillyp2p です。他の FPGA 用プロトコルには、アプリケーションロジックでフロー制御を実装する際に役立つ機能がほんのわずかあるだけです。

このページでは、フロー制御を実装するためのいくつかのテクニックを説明します。Aurora と Interlaken がフロー制御にどう役立つかについての簡単な要約は、後で示します。ただし、Xillyp2p を使う場合を除いて、オーバーフローを防ぐ責任があるのはアプリケーションロジックであることを覚えておくことが重要です。

フロー制御の手法

フロー制御の究極の目標は、データを受信する側が処理できる量を超えるデータを受け取ってしまう状況を防ぐことです。通常、受信側は到着したデータをバッファ(または FIFO)に蓄えるため、結局のところ、到着するすべてのデータのためにバッファの空き領域を確保することが重要になります。

MGT で使うフロー制御の実装はより困難です。主な理由は、物理チャネルの遅延が大きいことです。そのため、データ送信を停止する要求が送信側に届くまでに時間がかかります。さらに、送信側がデータ送信を停止してから、受信側へのデータ到着が止まるまでにも一定の時間があります。

また、MGT に関するもう 1 つの難しさは、物理チャネル上のビット誤りによって、データ送信を停止する要求が失われる可能性があることです。

これら 2 つの難しさに加えて、MGT のデータレートは高く、この物理データチャネルを効率的に使うことが通常期待されます。

より単純な通信チャネル、例えばシリアルポート(RS-232)と比較すると、MGT のフロー制御は、オーバーフローが発生しないことを保証するためにより高度である必要があります。以下で、次の 3 つの手法を説明します。

プロジェクトへの採用を検討する際には、次の 2 つの問いを発することが重要です。

インバンドとアウトオブバンド

これら 3 つの手法を個別に説明する前に、インバンドフロー制御(in-band flow control)とアウトオブバンドフロー制御(out-of-band flow control)の違いを明確にしておくことが重要です。

どのようなフロー制御メカニズムでも、受信側はデータの流れを調整するために、送信側へ要求または情報を送る必要があります。多くの実際の使用シナリオでは、両方向に物理データチャネルがあります。つまり、受信側にも、データを送信するための逆方向の同等な物理チャネルがあるというわけです。

逆方向の物理チャネルが存在する場合、そのチャネルがフロー制御要求の送信に使われるかどうかが問題になります。そのチャネルがこのように使われる場合、そのメカニズムはインバンドフロー制御と呼ばれます。それ以外の場合は、アウトオブバンドフロー制御が適用されます。

一般的に言えば、アウトオブバンドフロー制御はそれほど洗練された解決策ではありません。特に、この目的のために別個の物理配線が必要になるからです。しかし、MGT のチャネルが一方向である場合には、これが唯一の可能性です。

このトピックについては、Interlaken がフロー制御を実装する方法に関連して、後ほどさらに説明します。

それでは、3 つのフロー制御手法について説明しましょう。

XON / XOFF

XON / XOFF は、transmit on / off(送信オン/オフ)の略です。これは最も単純なフロー制御メカニズムですが、いくつかの重大な欠点があります。

この方法はさまざまな形で実装できますが、考え方は常に同じです。受信側がそれ以上データを受け入れられないとき、送信側に対して「今すぐ送信を停止せよ」という意味の何らかのメッセージを送ります。これが XOFF の意味です。その後、受信側がデータを受け入れられるようになったら、データフローの再開を要求するため XON が送信されます。これらの要求は単純なので、インバンドでもアウトオブバンドでも送信に適しています。

MGT を使ったフロー制御について上述した難しさはすべて、XON / XOFF 方式で顕在化します。最初の難しさは、XOFF 要求が送信側に届くまでに時間がかかることです。送信側はこの要求が届くまでデータを送り続けます。さらに、要求が届いた時点で既に物理チャネル上にあるデータは、引き続き受信側に到着し続けます。

したがって、受信側は、その後に到着するデータをまだ処理できるように、十分早く XOFF を送らなければなりません。しかし、どの程度早ければ「十分早い」のでしょうか。これは物理チャネルの往復時間(round-trip time)に依存します。シナリオによっては、このパラメータが既知であるか、少なくとも往復時間が短いことが分かっています。

例えば、SATA プロトコルは XON / XOFF を使用します。これは理にかなっています。このプロトコルは、SATA コントローラの物理的に近くにあるハードディスクとの通信を意図しているからです。2 つのリンクパートナー間の距離が不明で、しかも長い可能性がある場合、XOFF を要求する最適なタイミングを定義するのは難しいことがあります。

もう 1 つの要素は、送信側が XOFF を受信したときに即座に停止できるかどうかです。例えば、送信内容がパケットで構成されている場合、プロトコルはパケットの途中で送信を止めることを許さないかもしれません。XOFF や XON を送信する条件を定義するときには、すべてのシナリオを考慮しなければなりません。

もう 1 つの問題は、ビット誤りや物理チャネルの他の障害によって XOFF メッセージが失われた場合にどうなるかです。この場合、送信側はデータフローを続け、オーバーフローを引き起こす可能性があります。したがって、プロトコルは、XOFF 要求が失われる可能性がある場合に送信が停止されることを保証しなければなりません。Interlaken がこの問題にどう取り組むかについては、後述します。

このメカニズムをまとめると、XON / XOFF は単純な概念に基づいていますが、この方法でオーバーフローが決して起こらないことを保証するのは残念ながら難しく、予期しないシナリオに注意深く対処する必要があります。次に説明するクレジット方式は、その鏡像です。理解するのは複雑ですが、目標を簡単に達成できます。

時間制限付き XOFF(Time-limited XOFF、"Pause")

時間制限付き XOFF は、XON / XOFF 方式の亜種です。フロー制御要求に数値が付加されます。この数値は、送信側が要求を受信した時点から、どのくらいの期間データ送信を休止すべきかを示します。より正確には、送信側がデータを送信してはならないクロックサイクル数です。この方法は、Ethernet の PAUSE フレーム(Pause frame)に似ています。

この方法の利点は、その後に XON が不要なことです。この特徴は特定の状況で役立つことがありますが、その場合でも利点はかなり小さいものです。

時間制限付き XOFF をここで取り上げる唯一の理由は、この方式が Aurora プロトコルの一部であるためです。

クレジット(credits)

クレジットとは、通信チャネルが初期化されてから送信が許可されるデータ要素の数の上限です。この数は、プロトコルで定義された何らかの制御チャネルを通じて、受信側から送信側へ送られます。これによって、受信側は自分に送られてくるデータ量を制御します。

これは単純な例で説明するのが一番です。受信側のバッファが最初に 1000 個のデータ要素を受け入れられるものとしましょう。これに応じて、受信側はクレジットが 1000 データ要素であることを示すメッセージを送信側へ送ります。送信側は 1000 個のデータ要素をすぐに送信してもよいし、後で送信してもかまいません。ただし、クレジットが更新されない限り、送信側が送信するデータ要素の合計数は 1000 を超えません。

しばらく時間が経過し、500 個のデータ要素が受信側に到着したとします。その間に、アプリケーションロジックは 100 個のデータ要素を消費しました。この状況では、バッファ内に 400 個のデータワードがあるので、バッファにはさらに 600 個のデータ要素のための空きがあります。

この時点で、受信側は別のメッセージを送り、クレジットを 1100 に更新します。これは、500 個のデータ要素が既に到着し、さらに 600 個が許可されていることを反映しています。たとえアプリケーションロジックがバッファからデータを消費しなくてもです。したがって、送信側が最初から合計 1100 個のデータ要素を送信していれば、バッファは満杯になります。別の見方をすると、受信側はバッファから消費されたデータ要素の数だけクレジットを常に増やしているのです。

このメカニズムにより、オーバーフローは防止されます。送信側は、受信側が許可した量を超えるデータを決して送らないからです。ただし、この方式には注意を要する小さな問題が 2 つあります。

最初の問題は、受信側と送信側が、送信されたデータ要素の数がゼロである開始点に同意しなければならないことです。これには、両側がカウンタをリセットする何らかの初期化手順が必要です。クレジットを使うすべてのプロトコルには何らかの初期起動手順があります。両側が同時にある状態から別の状態へ移行できなければならないため、これはプロトコルを複雑にします。

2 番目の問題は、データフローが永久に継続できる必要があることです。クレジットは常に増え続けます。クレジットを限られたビット数の数値として送るにはどうすればよいのでしょうか。この問いに対する答えは、クレジットのバイナリ表現の下位部分(すなわち、下位ビット(LSB)だけ)を送れば十分だということです。送信側は同じビット数を使って、自分が送信したデータ要素の数を表します。

これで十分なのは、送信側がクレジットを、送信が許可されるデータ要素の数を計算する目的にしか使わないからです。この数は、クレジットから、自分が既に送信したデータ要素の数を引いて計算されます。その結果は、受信側のバッファのサイズより大きくなることはありません。この数が 2n より小さい場合、n 個の最下位ビットより上のビットはすべてゼロです。したがって、それらを計算しても意味がありません。n ビットだけで減算を行えば十分です。そのため、フロー制御要求では、クレジットのバイナリ表現の下位 n ビットだけが必要なのです。

例えば、PCIe のフロー制御は、フロー制御が保護するバッファの種類に応じて、クレジットを 8 ビットまたは 12 ビットのバイナリワードとして送信することに基づいています。

クレジットを使うことには多くの利点があります。

Interlaken でのフロー制御

Interlaken プロトコルは、別のページで簡単に紹介しています。

フロー制御の議論のために注意しておくと、このプロトコルは各データバーストにチャネル番号(通常 0〜255)を割り当てます。言い換えると、このプロトコルは、物理チャネルを共有する複数のアプリケーションデータストリームという考え方に基づいています。したがって、フロー制御メカニズムは、アプリケーションデータの各ストリームを独立して制御します。

このプロトコルは 2 種類のフロー制御メカニズムを提供します。インバンドフロー制御とアウトオブバンドフロー制御(OOBFC)です。どちらも XON/XOFF メカニズムです。ステータスは各チャネルにつき 1 ビットで伝えられます。このビットは、そのチャネルがデータを受信する準備ができているときは '1'(XON)、それ以外のときは '0'(XOFF)です。

これら 2 つのメカニズムの違いは、これらのビットがどのように送信されるかです。インバンドフロー制御メカニズムは、各バーストの前後に制御ワードが送信されるという事実に依存しています。この制御ワードは 64 ビットで構成され、そのうち 16 ビットがフロー制御の目的に割り当てられています。これにより、各制御ワードにつき最大 16 個の XON / XOFF 要求が可能です。しかし、これは最大 256 チャネルをサポートするには十分ではありません。各チャネルには独自の XON / XOFF ビットがあるからです。これを解決するため、フロー制御情報は複数の制御ワードに分割されます。この方法はカレンダー(calendar)と呼ばれます。制御ワードのビット 56 は「Reset Calendar」と呼ばれます。このビットが '1' の場合、その制御ワードはチャネル 0〜15 に関する XON / XOFF 要求を含みます。次の制御ワードにはチャネル 16〜31 の要求が含まれ、以下同様に続きます。すべてのチャネルがカバーされると(場合によっては制御ワード 1 つだけでも)、「Reset Calendar」を使ってシーケンスが再開されます。

バーストの CRC24 によってビット誤りが検出されると、すべてのチャネルが XOFF 状態になります。その理由は、CRC24 が制御ワードもカバーしているため、エラーが検出された場合にフロー制御部分が無視されるからです。したがって、そのようなイベントが発生した後は、どのチャネルで送信しても安全ではありません。通常動作は、後続の制御ワード内のフロー制御要求に基づいて徐々に再開されます。

インバンドフロー制御の主な欠点は、XON / XOFF 要求の配信が、同じ方向に送信されるデータバーストに依存することです。これらのバーストが長い場合や、しばらくの間バーストがまったく送信されない場合、XON / XOFF の配信に時間がかかることがあります。同じ物理チャネル上で送られるデータ転送とフロー制御メッセージが帯域幅を奪い合うのは避けられないため、これはある程度は正当化できます。しかし、他のプロトコルは通常、フロー制御メッセージを優先し、一貫した最大遅延を保証しています。

アウトオブバンドフロー制御(OOBFC)は、データバーストとの競合を回避します。この方法では、XON / XOFF 要求は追加の 3 本の物理配線(FC_CLK、FC_DATA、FC_SYNC)を通じて送信されます。すべてのチャネルの XON / XOFF ビットは、1 つの長いフレームで送信されます。

FC_SYNC 信号は、このフレームの最初のビットと一緒にハイになります。FC_CLK の周波数は 0〜100 MHz で、DDR クロッキングも許可されています。4 ビットからなる CRC(CRC-4)は、64 個の XON / XOFF 要求の後、または最後の要求の後に挿入されます。CRC によってエラーが検出されると、すべてのチャネルが XOFF 状態になります。

インバンドフロー制御とアウトオブバンドフロー制御のどちらを選ぶかは、もちろんプロジェクトの要件次第です。

Interlaken には、チャネルからのデータを多重化するメカニズムは含まれていません。したがって、チャネルからのデータ送信要求の調停を行い、どのチャネルがバースト(またはパケット全体)を送信できるかを選択するのはアプリケーションロジックの役目です。したがって、XOFF が必要とする場合に特定のチャネルの送信を一時停止するのも、アプリケーションロジックの責任です。Interlaken プロトコルを実装するロジックは、XON / XOFF 要求の送受信のみを担当します。

このプロトコルは、フロー制御を実装する可能性としてクレジットに言及していますが、それは専用チャネルを使ってこの方式を実装するための自由な提案にすぎません。その実装方法についての詳細はプロトコルにはありません。

Aurora でのフロー制御

Aurora プロトコルは、別のページで簡単に紹介しています。このプロトコルは、フロー制御を容易にするための 2 つのメカニズムを提案しています。NFC と UFC です。この 2 つについて、以下でそれぞれ説明します。

まず、ネイティブフロー制御(Native Flow Control、NFC)です。このメカニズムでは、受信側のアプリケーションロジックが、フロー制御要求を送信側へ送るためのインターフェースを持ちます。これらの要求には 2 つの独立した部分があります。XOFF ビットと、時間制限付き XOFF(「pause」)の部分です(どちらの概念も上で説明しました)。送信側のプロトコルロジックは、これらの要求に従う責任があります。XOFF ビットが '0' の場合、送信側は、フロー制御要求に含まれる 8 ビットの数値に対応するクロックサイクル数の間、データ送信を一時停止します。この数値がゼロの場合、データ送信は直ちに再開されます。要求内の数値は累積しません。各 NFC 要求は、一時停止のカウントダウンを新しい値で更新します。

XOFF ビットが '1' の場合、送信側はデータ送信を無期限に一時停止します。送信側がデータ送信を再開するのは、XOFF = '0' のフロー制御要求に応じたときだけです。そのような要求は前述のように処理されます。

このフロー制御メカニズムは、物理データチャネルを通るすべてのデータトラフィックを制御することに注意してください。したがって、NFC は、複数のチャネルが実装されている場合、それらを個別に制御するのには適していません。

2 番目のメカニズムはユーザーフロー制御(User Flow Control、UFC)です。これは実質的には、最大 256 バイトのメッセージを相手側へ送信するための別のチャネルです。UFC メッセージはデータの送信より高い優先度を持つため、低遅延で相手側に届きます。

プロトコルはこれらのメッセージの形式を定義していないため、あらゆるタイプのフロー制御の実装に使えます。そのような実装はすべてアプリケーションロジック内で行われます。UFC メッセージは、他の種類のステータス情報の送信にも使用できます。

これら 2 つのフロー制御メカニズムで使われるメッセージのいずれも、物理リンク上のビット誤りから保護されていないことに注意してください。したがって、フロー制御要求が誤って到着したり、まったく到着しなかったりする可能性があり、受信側でオーバーフローを引き起こす可能性があります。

両方のフロー制御メカニズムは逆方向のデータリンクに基づいているため、これらは全二重モードでのみ利用可能です。

まとめ

このページでは、主に 2 つのフロー制御手法を紹介しました。XON / XOFF とクレジットです。コンピュータ関連のプロトコル(例:PCIe、SuperSpeed USB、SATA)では、フロー制御はプロトコルのロジックによって実装されます。一方、FPGA 間の通信用プロトコルでは、実装のすべてまたは大部分をアプリケーションロジックが担当します。唯一の例外は Xillyp2p で、フロー制御、エラー検出、再送を含むデータ通信のすべての側面を処理します。

FPGA 用の 2 つのプロトコル、Interlaken と Aurora のフロー制御関連機能を紹介しました。示したように、これらのプロトコルは、特定の使用シナリオではプロトコル自身の機能が一部の作業を行うことがあるものの、フロー制御の実装の大部分の負担をアプリケーションロジックに残しています。

以上で、MGT に関するこの一連のページの最後のページを終わります。

このページは英語から機械翻訳されたものです。不明な点があれば、原文を参照してください。
Copyright © 2021-2026. All rights reserved. (dcc38493)