FPGA の高速シリアルトランシーバ (1)

このコースでは、最近の高性能 FPGA にはほぼもれなく搭載されている高速シリアルトランシーバを使ったシリアルリンクについて紹介していきたいと思います。高速シリアルトランシーバは PCI Express や Ethernet, USB のような標準インタフェイスを FPGA に実装する際にも用いられますし、FPGA どうしを直結するための専用のプロトコルも各 FPGA ベンダから提供されており、広く応用されています。多くの場合、これらは IP コアによってブラックボックス化されていて、設計者がトランシーバを直接扱うことはあまりありません。しかし、自分でトランシーバを扱う設計をゼロからできると、さらに応用範囲を広げることができます。

そこで、このコースでは、Xilinx の FPGA どうしを直接接続するために提供されている Aurora 64B/66B の IP コアの挙動やそのプロトコルについて解説し、さらにそれをオープンな形で実装しなおした事例について紹介していきます。プロトコルは公開されていますし、トランシーバの電気的なインタフェイスは FPGA ベンダに依らないので、Intel の FPGA に同じプロトコルを実装することも可能ですし、これをもとにして自分で新たな拡張プロトコルを設計することもできます。

シリアル伝送とパラレル伝送

パソコンをはじめとするデジタルシステムには、プリント基板上の LSI どうしのデータ通信を行うための配線や、あるいはほかのシステムと通信するための配線があります。たとえば、CPU とメモリの間の配線が前者ですし、USB などは後者になります。もともとは、高速伝送にはパラレル伝送、シリアル伝送は配線が少なくて済むので長距離の伝送に使われてきました。下の写真は筆者が1994年頃に購入した外付け SCSI ハードディスクですが、パソコン本体とのインタフェイスは50ピンのケーブルで、8bit のバスを 5MHz で駆動、最大データ転送レートは 5MB/s でした。

外付け SCSI ハードディスクのインターフェース

パラレル伝送で速度を上げるにはバスの動作周波数を上げるか、ビット幅を広げる必要があります。しかし、そうすると配線長のばらつきで全部のビットが転送先に届くタイミングがばらついたり、ノイズの影響を抑えるのが大変です。実際に、ハードディスクなどの接続に用いられていた SCSI という規格では、世代が進んで動作速度が上がるごとにケーブルの最大長が短くなっていきましたし、一般向けのパソコンの PCI バスは 32bit/33MHz より高速になりませんでした (サーバなどではより高速な PCI, あるいは PCI-X バスが用いられていましたが。)

一方、シリアル伝送ではそもそも配線が1本しかないのでタイミングのばらつきの問題はありませんし、配線が少なければノイズ対策も容易です。パソコンの周辺でも、2005年頃から USB や PCI Express といったシリアルインタフェイスが一般的に使用されるようになりました。USB は当初 12Mbps でしたが、USB 2.0 で 480Mbps のモードが追加されると、さきほど紹介した SCSI インタフェイスの10倍以上の転送速度になり、ハードディスクをはじめとしていろいろな機器の接続に使用されています。

高速シリアル伝送の原理

そのまえに、UART の話

シリアル伝送ではデータの送受信に使う信号線は基本的に1本しかないので、

  1. 送受信を行う双方でタイミングを合わせる
  2. データ (1バイト、あるいはそれより長いワード) の境界を認識する

ための仕組みが必要です。あまり高速でないシリアル伝送の代表と言えば、RS-232C でおなじみの UART (Universal Asynchronous Receiver/Transmitter) です。これはその名の通り Asynchronous な通信方式で、1ビットを送る時間の長さだけ決めておき、いつデータを送るかはその都度決めましょう、というやり方で、簡単に図にすると次のような波形になります。

UARTによる伝送の例

データを送信していない間は通信ラインを H レベルにしておき、データを送信する前に L にして1ビットの0を送信します。これを「スタートビット」と呼び、データを送信する合図になります。1ビットの長さ (時間) はあらかじめ決まっていますから、スタートビットの送信開始のタイミングから時間を計って1ビットずつ送受信すれば正しくデータを転送できます。最後に、次のスタートビットの送信に備えて最低1ビット分のストップビットを送るのが普通です。

RS-232 では送受信各1本の信号線を用い、H と L の識別は共通の GND レベルから、それぞれ ±5〜15V と、振幅を大きくとることで 10m 程度の長距離でも安定した通信を実現しています。しかし、振幅が大きければ高速化には不利です。そこで、RS-422 では送受信にそれぞれ2本の信号線ペアを使用する平衡伝送 (差動信号)が採用され、最大で 192kbps 程度だった RS-232 に対して 10Mbps の速度を実現しました。この平衡伝送の仕組みは、高速シリアルトランシーバにも使われています。

また、UART では送受信の双方ではあらかじめ1ビットの長さを決めておくことはしますが、クロックを同期することはしないので、そのまま高速化することは困難です。これについては、次のセクションで解説します。

符号化とクロックデータリカバリ

UART では受信側のクロックを送信側と同期しないため高速化が困難でした。しかし、クロックのために配線をもう一本追加する、というのはできればとりたくない方法です。そこで、高速シリアル伝送ではクロックデータリカバリという手法が用いられます。これは、受信側ではおおよそ同じ周波数の基準クロックを用意しておき、さらに受信するデータにほどよく1と0が混じっていれば受信側で正確に送信側のクロックを復元できる、というアイデアです。

このアイデアを実現するには常に1と0が「ほどよく混じった」データを送受信することが必要になりますが、シリアル化されたビット列で1と0が切り替わる確率はデータの性質によって変わってきます。特に、「何も送信していない状態ではずっと0を送る」ようなシステムの場合、1と0の切り替わりがまったく起きないようなことも考えられます。

そこで IBM によって開発されたのが 8b/10b コーディングによる符号化です。これは、次の表のように256個の「Dキャラクタ」からなり、これにそれぞれが対応する8ビット2進の値と10ビットの符号を割り当てる符号化方式です。これによって1バイトを10ビットに符号化すると、0か1のどちらかが長く続くことがなくなり、データからクロックを復元できるようになります。このほかに、K キャラクタと呼ばれる制御文字もいくつか定義されており、これはリンクの制御のために使われます。

名前8ビットCurrent RD-Current RD+
D00.00x00100111 0100011000 1011
D01.00x01011101 0100100010 1011
D30.70xFE011110 0001100001 1110
D31.70xFF101011 0001010100 1110
8b/10bコーディングの符号

8b/10b コーディングについては詳しいことは Web にもさまざまな記事があるのでここでは省略しますが、8ビットのデータと10ビットの符号は辞書による相互変換が必要です。1つの8ビットの値についてふたつの符号が割り当てられていますが、これをうまく使うことで誤りを検出する仕組みも実現できるようになっています。

8b/10b コーディングは Gen1 および Gen2 の PCI Express や、初期の 10Gbit Ethernet (2.5Gbps の物理リンクを4本用いるもの) に用いられました。また、JESD204 という標準に基づく高速 AD/DA コンバータのインタフェイスとしても使われています。しかし、8ビットのデータを10ビットの符号に変換するため、25% ものオーバーヘッドが生じます。このため、最近のより速いシリアル通信規格では 64b/66b や 128b/130b などの、より符号化効率の高い方式が採用されています。これについては、このコースの続きの回で説明したいと思います。

しかし、8b10bコーディングを単に使うだけでは、UARTと違ってスタートビットに相当するものがないため、送られてくるビット列をどこから10ビットずつ区切ったら正しく復号化できるのかがわかりません。このためには、電源が入ったりケーブルが接続された際のリンク初期化の際に、何らかの方法で符号 (あるいはバイト境界、ワード境界) を識別する必要があります。これは8b10bコーディングだけでは規定されていませんので、8b10bコーディングだけでは通信ができず、EthernetやPCI Express、あるいはAuroraなど、それぞれの上位プロトコルでリンク初期化のシーケンスを規定することになります。

シリアルトランシーバのハードウェア

ここまででシリアルトランシーバを使って通信する仕組みについてざっと説明してきました。ここからはシリアルトランシーバのハードウェアについて見ていきます。この記事では FPGA に搭載されいてるシリアルトランシーバについて、ということになりますが、FPGA に限らず、ASIC に搭載されるトランシーバ IP コアでも基本は同じです。

差動信号の種類と伝送メディア

高速な平衡伝送を行うための差動信号の方式としては、LVDS (Low Voltage Differential Signaling)、LVPECL (Low Voltage Positive ECL)、CML (Current Mode Logic) などがあります。CML は高速性にすぐれているため、PCI Express, Serial ATA をはじめとしてさまざまな規格で用いられており、FPGA のシリアルトランシーバもこの方式です。LVDS や LVPECL は FPGA の通常のユーザ I/O で使用することができます。

差動信号ですから、送受信それぞれ正負の2本の信号線が必要です。下の写真は送受信のメディアとして同軸ケーブルを使っている例ですが、送受信あわせて4本のケーブルが写っているのが確認できます。

トランシーバへの同軸ケーブル接続

しかしこれではケーブルを接続したり取り外したりにそれなりの手間がかかりますし、同軸ケーブル4本の取り回しもやっかいです。FPGA ボードを直結するならば SFP や QSFP といった、10Gbit Ethernet や 40Gbit/100Gbit Ethernet で使われるケーブルを使うのが簡単です。SFP なら送受信各1ペア、QSFP では各4ペアの信号線がケーブルを通っており、短いものであればケーブルにただ銅線が通っている安価なもので大丈夫ですし (Passive Copper Cable)、長いものが必要ならば光トランシーバを組み込んだ AOC (Active Optical Cable) を使うこともできます。どちらも電気的なインタフェイスは変わらず CML です。

SFPケーブル(左)とQSFPケーブル(右)

同軸ケーブルや SFP/QSFP のほかに、PCI Express のコネクタを備えている FPGA カードもありますが、いずれのコネクタもトランシーバの CML の信号線がそのまま出ており、物理層の仕様としては同じです。また、FMC コネクタを備える FPGA カードの場合、下の写真のような、各種のコネクタを接続するための FMC カードを利用することもできます。

FMC-SMAカード(下)とFMC-SFPカード(上)

トランシーバの構造

トランシーバはアナログ回路を含む専用ブロックなので、FPGA の大部分を占めるロジックファブリックとは別に、通常はデバイスの一番端に配置されています。下の図は、FPGA 上のシリアルトランシーバと、64b/66b コーディングで 10.0Gbps のデータを送受信する場合の各部のクロックレートの例を示したものです。クロックレートなどの数字はもうすこしあと、このコースの3回目か4回目で説明します。

FPGA 上のシリアルトランシーバの例

それでは、トランシーバのそれぞれの構成要素について説明していきましょう。まず、トランシーバは一対の送信 (Tx) と受信 (Rx) 回路でチャネルを構成し、4〜6チャネルでひとつのグループになります。グループごとに2つ程度の共有 PLL が備えられており、これでチャネルを駆動するクロックを生成します。

デバイスの一番外側、シリアル信号の伝送路に直接つながっているところは PMA(Physical Medium Attachment) と呼ばれ、アンプを含む送受信回路のほかに、シリアルーパラレル変換を行うシリアライザ (送信側)、あるいはデシリアライザ (受信側) が搭載されています。送信側の PMA は共有 PLL のクロックで駆動され、受信側の PMA は共有 PLL のクロックを参照しながらクロックデータリカバリを行い、受信側の回路はこれに同期して動作します。

PMA とロジックファブリックの間にあるのは PCS(Physical Coding Sublayer) です。PCS には 8b/10b エンコーダ・デコーダをはじめとして、各種のプロトコルの実装に役に立つオプション機能が搭載されていますが、なかでも一番重要なのはギアボックスと呼ばれる回路です。PMA と PCS のインタフェイスは32、40、64などの限られたビット幅だけが選択できますが、ギアボックスはシフト回路と FIFO で構成されており、ロジックファブリックのユーザ回路に対して 66bit や 67bit、その他さまざまなビット幅のインタフェイスを提供します。これによって、各種のプロトコルの実装が容易になります。なお、特殊なカスタムプロトコルを実装する場合には PCS をバイパスして、ギアボックスを含むさまざまな機能をロジックファブリック上に実装することも可能です。

ギアボックスとリンク初期化

ところで、送信する側はただビット列を送り続けるだけなので問題は起きませんが、受信側では PMA も PCS も、受信されるデータのワード境界を自分でみつけることはできません。そこで Rx PCS のギアボックスにはビットスリップと呼ばれる仕組みが用意されています。FPGA のロジックファブリック側からギアボックスへビットスリップ信号が用意されており、これを H にするとギアボックスのワード境界が1ビット移動します。

この仕組みを利用して、電源オンやケーブル接続時のリンク確立のための手順を実装することが可能です。8b/10b や 64b/66b をはじめとして、この種の高速シリアルリンクを用いるプロトコルではいずれも、

  1. リンクが確立されていない場合には互いに一定の制御文字 A を連続送信
  2. リンクパートナーからこの文字を受け取った場合には別の制御文字 B を連続送信
  3. 自分が2.の制御文字を一定数以上送り、相手からも同じ制御文字を一定数以上受け取ったらリンク確立と判断する

という手順がとられます。電源オン直後やケーブルが接続されていなかったり、接続直後には 1. の状態ですから、決まった制御文字を連続送信します。この時には Rx PCS のギアボックスは正しくワード境界を認識していないので、一定間隔でビットスリップを繰り返します。こうすることで、ケーブルが正しく接続されれば、どこかで制御文字 A または制御文字 B を受け取れるようになるので、その先に進むことができます。ここで使う制御文字には、8b/10b コーディングでいうところの「K キャラクタ」のような、通常のデータには出現しない文字を用います。これによって、送っていたデータがたまたま初期化シーケンスと一致して誤動作が発生する、ということを防いでいます。

また、一旦リンクが確立したと判断したのちも、何らかの致命的なエラーを検出した、と判断した段階で 1. のステップに戻るようにしておくことで、ケーブルの抜き差しやその他のエラーが発生した場合に、自動的にリンクを復旧することができます。

まとめ

今回は高速シリアルリンクで用いられる符号化方式や電気的な規格、そしてシリアルトランシーバの基本的な構成と、物理層のひとつ上のデータリンク層に必要になるリンク確立手順の実装に必要となる機能などについて解説しました。

次回はふつうの FPGA 設計者の視点から、Xilinx の Aurora 64B/66B コアを例に、FPGA どうしを直結するための IP コアを生成し、シミュレーションします。今回は PMA と PCS, PCS とロジックファブリックの間のクロック周波数の違いなどについては詳しく説明しませんでしたが、次回以降でこのあたりをご理解いただけるように解説していきたいと思います。

琉球大学 長名保範

タイトルとURLをコピーしました