EZ-USB FX3とFPGAをつなげて動作テスト
ようやく重い腰を上げてEZ-USB FX3のSlaveFIFOとFPGAをつなぐ実験をしています。
FX3のSlaveFIFOは、GPIF IIを利用して作られています。FX2のGPIFはSlaveFIFOに内部でステートマシンを付け加えたものだったのですが、FX3では逆にGPIF IIのほうが先に存在していて、SlaveFIFOの各種信号をGPIF IIで作り出しているようです。
このデフォルトのSlaveFIFOの使い方がわかってきました。
・受信のやりかた
[A1:A0]="11"にして、SLCSを'0'にすると、数クロック後にFLAGAに読み出しFIFOの状態が出力される。FLAGAが'1'ならデータあり。その場合、SLCS=0、SLRD=0、PKTEND=1、SLOE=0にしてデータを読み出す。FLAGA='0'になったら終了。
・送信のやりかた
[A1:A0]="00"にして、SLCSを'0'にすると、数クロック後にFLAGAに書き込みFIFOの状態が出力される。FLAGAが'1'ならFIFOに余裕あり。その場合、SLCS=0、SLWR=0にしてデータを与えることができる。FLAGA='0'になったらFIFOがいっぱい。ただし、FLAGAの反応は鈍いので、最後の3個分くらいのデータはFIFOに入らずに破棄されるらしい。
どうしてもSlaveFIFO接続がうまく動かないな~、という時があるのですが、いろいろわかってきたことがあります。
① ファームウェアを更新すると、GPIF IIが動かなくなることがある。その場合、リセットではなく電源ON/OFFしたほうがよい。
② ファームウェアの転送前にFLAGA、FLGAGBにノイズが入ると、GPIF IIが動かなくなることがある。
③ そもそもFLAGAとFLAGBの区別がよくわからん。(GPIF IIの設定による)
④ インタフェースクロックを50MHzにするとデータが化ける?100MHzならOK。要検証。
⑤ Read時には、PKTENDを1にしておかないと全く動かない。
⑥ A0,A1を操作してからFLAGA、FLAGBが変化するまでに2~3クロックかかる。遅い!
⑦ そもそもPCLKを入れないと、FLAGA、FLAGBがハイインピーダンスのまま動かない。
⑧ SlaveFIFOとFPGAの間は100MHzの速度で、16あるいは32bitでインタフェースできるので、1つのパケットの読み出し速度は最大400MB/secになる。しかし、パケットとパケットの間隔が平均して90μ秒かかっているので、毎秒平均して11MB/secしかでない。IN方向もOUT方向も同じ。
とりあえずSlaveFIFOとFPGA間で接続はできるようになってきたのですが、どうしても速度が出ません。
これはFPGAの回路や、ファームウェアの問題ではなく、おそらくCyUSB.sysのデバイスドライバに問題があるか、EZ-USB FX3のライブラリの問題か、何かのディスクリプタの設定が忘れていてバースト転送できないようになっているとしか思えないような動作です。
※USB_SUPERSPEED_ENDPOINT_COMPANION_DESCRIPTOR をいじったり、USBEndPoint->ssmaxburstをいじっても変化なし。
下の写真は、SLRD(あるいはSLWR)とFLAGAの状態を表したものです。
FLAGAが'1'になると、FIFOにデータがある(あるいは書き込み可能)を示します。それを見てSLRD(あるいはSLWR)を与えているのですが、1024バイトを転送(5.12μ秒)した後、次のFLAGA(データあり)が送られてくるまでに数十μ秒かかってしまっています。
なお、CypressのControlCenterに代わるプログラムを自作しています。コマンドラインからRAMへのダウンロードと、I2C ROMへのダウンロード、BulkIn、BulkOutの操作ができようになりました。

実験に用いているSlaveFIFOのファームウェアと、FPGAのデザイン、コマンドラインアプリは、こちらからダウンロードできます。
| 固定リンク




コメント
DMA Channel のバッファがいっぱいになると、次のバッファに切り替える必要があります。この切り替えにかかる時間が、転送速度が高くなると無視できません。
切り替え時間が見えなくなるようにするには、バッファのサイズをパケットの数倍に大きくしてやります。また、 bulk burst の数を同じく数倍にしてやることで、パケットがまとめて送信されるようになります。
切り替え時間をキャンセルするもう一つの方法は、 DMAMultiChannel を使うことです。複数の Socket を束ねてエンドポイントに接続するため、ある Socket でバッファの切り替えが始まっても別の Socket を使ってデータを送受信することができます。
SlaveFIFO のステートマシンを GPIF II Designer で見てやるとわかるのですが、 PKTEND をアサートしていると READ シーケンスに入ることができません。 PKTEND は、 WRITE シーケンスに必要な信号なので、 READ 動作時にはネゲートしておいてください。
投稿: noritan.org | 2012.04.24 23:10
noritan様、情報ありがとうございます!
SlaveFIFOならびにGPIF IIは理解するのが大変だったので、SDKのサンプルファームウェアをそのまま使っていたのですが、やはり理解して自分でカスタマイズしないといけないようですね。
SlaveFIFOはハードウェアだけで動いているのかと思っていたのですが、DMAも絡んでいるようで、大変そうです。
投稿: なひたふ | 2012.04.25 15:12