EZUSB FX2のSlaveFIFOをCPLDでアクセス
昨日(土曜日)、EZ-USB FX2を載せる基板ができあがってきました。
スキャナでパターンの一部を読み取ってみます。
最近、基板や小さな部品は、スキャナで結構きれいに撮れることに気が付きました。
この基板にはEZ-USB FX2LPのQFPパッケージ版とCoolRunnerIIが載っています。昔使ったLowPower版ではないEZ-USB FX2は発熱がすごかったので、今回の基板は放熱を考慮したパターンで設計しましたが、そこまで苦労して設計する必要はなかったかもしれないです。EZUSB FX2LPはほとんど発熱しません。
さて、EZ-USB FX2は、EZなんていう名前がついていますが、全然Easyじゃありません。
サンプルのアプリやI/Oポートをアクセスさせるのは簡単ですが、FPGAやCPLDをつないで高速にデータを転送するとなると、とても難しいデバイスです。
インタフェース回路の設計
Webには載せていませんが、私はこの3年間くらいの間にEZ-USB FX2とFPGAを使っていくつかの装置を設計してきました。
それとは別に、今回、PLDとの接続インタフェース回路(IP)を1から作り直しました。
この回路は、SlaveFIFOを使ってEZ-USB FX2とPLDをインタフェースします。バス幅は8bitで、インタフェースクロックは48MHzです。エンドポイントはダブルバッファを構成します。
要はEZ-USB FX2から送られてくるフラグを実ながら、SLWRやSLRDといった信号を操作するだけの簡単なものですが、作ってみてEZ-USB FX2とPLDを48MHzでアクセスするのは非常に難しいと実感しました。
なぜならば、48MHzということはクロックの周期は約21nsですが、EZ-USB FX2が要求するSLRDやSDWRといった制御信号のセットアップ/ホールドタイムは、10数ns/数nsしかありません。PLDが出力する信号の遷移できる時間の幅は僅か5nsくらいしかないのです。
しかし、何より難しい点は、FIFOの状態を表すフラグがクロックから13.5ns秒後に変化することです。つまり、EZUSB-FX2から送られてくるフラグを見てデータの送信を止めるということは、タイミング的に間に合わないのです。
最近のCPLDやFPGAはとても高速ですが、チップの外から中に信号が入って出るにはやはり10nsくらいを要します。外とのインタフェースは、速くしようとすると、結構大変です。
そういうわけで、EZ-USB FX2とPLD間でタイミングをとるのは簡単ではありませんでした。裏クロックを使ったり、フリップフロップの後ろにゲートを置いてそのゲートが削除されないような仕組みを施したりで、ようやくEZ-USB FX2との48MHzでのインタフェースタイミングが満たせます。
IN方向のバルク転送
次の図は、CPLDで発生させた8MBytesの数列をホスト(パソコン)に送信したときの、SLWR信号の波形です。転送の方向は『IN』ということになります。
この「SLWR」信号がLになっているときにデータは送信されています。8MBytesのデータを送るのにおよそ236msかかっていますので、平均速度はおよそ284Mbpsということになります。
データサイズをいろいろと変えてみましたが、およそ260~290Mbpsの間のようです。
波形には疎密があるので拡大してみると、次の図のように周期的なパターンが繰り返しているのがわかります。
この信号がLに下がっている期間にデータがCPLDからEZ-USB FX2に送られています。その期間はおよそ10.6μ秒で、48MHzの速度で512バイト(USBの1パケット)を送る時間と等しくなっています。複数のパケット連続して送ろうとすると、データを送ることができない期間が規則的に表れますが、これはSlaveFIFOがFULLになっているため送信できない時間です。
FIFOがFULLになったままの期間はおよそ125μ秒周期で表れています。言い換えれば、およそ125μ秒の間に10個のパケットがほぼ規則正しく送信されているのがわかります。これはUSB2.0 HighSpeedでのマイクロフレームと関係があるのでしょう。
USB2.0のHighSpeedモードでは、1パケットは512バイトで125μ秒に5120バイト送れています。ここだけ見れば瞬間最大速度は328Mbpsも出ています。この調子でずっと125μ秒間に5120バイトを送りつづけることができれば、328Mbpsの速度でパソコンにデータを送ることができるはずです。しかし、実際には次の図のように「信号を送れない長い比較的長い期間」が生じてしまいます。こういう期間が結構な頻度で出現するため、実質的な速度は300Mbpsを切ってしまいます。
この波形を良く見ると、データを最大の効率で1.58ミリ秒送った後、データを送れない期間が200μ秒出現するということがほぼ周期的に出ています。データを送れた1.58ミリ秒の間には、1.58ms*328Mbps≒64700Bytesとなります。
実は、EZUSBのデバイスドライバは、デフォルトでは一度に64kBytesまでのデータしか扱えないので、64kBytesを超える大きなデータを送受信する際には64kBytes以下のサイズに細切れにしなければなりません。細切れにするということは、複数回DeviceIOControlを呼び出すということを意味します。
私のテストソフトウェアでは65024バイトに分割して送っているので、その影響が出ているのでしょう。
とにかく、64kBytesにデータを細切れにするということは、転送の効率を88%に低下させてしまうという結果になります。
すなわち、 『IN』方向のバルク転送は、今回のハードウェアでは328Mbpsが限界で、瞬間的にはこの速度が出るものの、大きなデータを転送する際にはデバドラのオーバーヘッドで効率が88%に下がり、CPLDからPCのメモリへの実質的な転送速度は288Mbps程度に下がってしまったと考えられます。
OUT方向のバルク転送
さて、逆にホスト(パソコン)からターゲット(作った装置)にデータを送る『OUT方向』の速度も測ってみたところ、8MBytesを送った場合、平均して230Mbpsくらいでした。
今度はSLRD信号をオシロで観察したところ、125μ秒周期の「マイクロフレーム」の間に8パケットしか受け取ることができていませんでした。このため、『IN方向』よりも速度が出ないようです。
波形を見る限り、125μ秒周期のマイクロフレームに8パケットですから、512Byte*8*8/0.000125で、瞬間最大速度は262Mbpsとなります。
次の図は、CPLDがデータを受け取る『OUT』方向バルク転送時のSLRD信号を数ミリ秒間にわたって観測した波形です。SLRD信号が激しく遷移してデータを受け取っている期間がおよそ2ミリ秒、SLRDが動かずデータが送られていない期間がおよそ280μ秒あり、それを周期的に繰り返しています。
この2ミリ秒の間に送信されたデータは、2ms*262Mbps≒65536Bytesです。本実験では8MBytesのデータをまとめて送っていますが、デバイスドライバの都合で64kバイト単位で細かく分割して送っています。このため2.28ミリ秒間に2.00ミリ秒分しかデータを送れず280μ秒はパソコン内でのデータの移動などに費やされています。要するに、デバイスドライバのために効率が87%に落ちてしまっています。
『OUT』方向のバルク転送は今回のハードウェア的には262Mbpsが限界で、瞬間的にはこの速度が出るものの、大きなデータを転送する際にはデバドラのオーバーヘッドで効率が87%に下がり、PCのメモリからCPLDへの転送速度は227Mbps程度になってしまったと考えられます。
まとめ
EZ-USB FX2やFX2LPのチップ自体は、USB2.0のHighSpeedモードを規格の範囲内でほぼ限界まで使うことができます。その性能を活かすことができるか否かは、接続するCPLD/FPGAの設計と、デバイスドライバの改良にかかっています。それは決してEasyではありません。
速度をより向上させるためには、DDKを用いてEZUSBのデバドラを再コンパイルして、バルク転送時のバッファサイズの最大値を64kBytes以上に引き上げる必要があります。
なお、今回の実験で送ったデータはテスト用の意味の無い数列で、メモリに格納されたあとすぐに破棄されてしまいます。これをハードディスクに格納したり画面に表示すれば、スループットはこれより下がるでしょう。
以前検証した際には、EZ-USB FX2とFPGAを16ビット48MHzモードでインタフェースした場合、もう少しスループットが出ていたような気がします。今製造中の次の基板が仕上がったら、16ビットモードでも実験してみることにします。
| 固定リンク
この記事へのコメントは終了しました。
コメント