« PCI Express転送テストアプリとデバイスドライバを更新 | トップページ | ノートPC「Eee PC S101」を自力で修理 »

2010.10.26

Spartan-6LXTの内蔵PCIe EndPointの使い方を理解した

ついに、Spartan-6LXTの内蔵PCIe EndPointの使い方を理解しました。
うーん、なんていうか非常に複雑で面倒です。

内蔵EndPointは、TLPの組み立てや解読を行うために、ユーザが自分でステートマシンや上位の回路(ソフトウェア層)を作らなければなりません。

確かに、CoreGenで内蔵EndPointのラッパを作ると簡単なサンプルデザインが自動で作られます。XILINXのSP605に付属しているサンプルデザインも基本的にはそれです。このサンプルはメモリ空間の読み書きができるので、一見すると良さそうなのですが、実はそのサンプルデザインには、「1DWのデータ転送しかサポートしていない」という制限があります。

これはかなり重大な問題で、ルートコンプレックス(パソコン)は4バイトを超えるメモリ・リード/ライトのリクエストを発行できないのです。つまり、LONGサイズでしかアクセスできませんから、転送速度は上りも下りも1~2MBytes/sec程度になってしまいます。もし、2DW以上のリードリクエストを発行したら、EndPoingは応答を返さないので、タイムアウトしてしまいます。(パソコンが一瞬固まります)

内蔵EndPointを使ったデザインを作るには、やはりCoreGenの自動生成サンプルではなく、一から作り直さなければなりません。

そこで、今まで作ってきた特電PCIe互換コアを使います。特電PCIe互換コアは、DMA転送や割り込みまでサポートしていて、それなりに高機能で、すぐに使えます。この互換コアは独自のデータリンク層や物理層回路をもっています。

一方、内蔵EndPointは、PCI Expressの規格への準拠や信頼性は優れています。(コンプライアンステストに通っているのですから)。そのため。特電PCIe互換コアのデータリンク層以下をSpartan-6LXT内蔵EndPointに置き換えれば、高機能と高信頼性が両立できるはずです。

今日は、内蔵EndPointの使い方を解明するとともに、そういう移植を行っていました。
少し苦労しましたが、できました。

下の図は、2DWのメモリ・リード・リクエストを受け取ったときの挙動です。
Sp6pciememrd2dw2
「00000002 000016FF FCFF6808」というのがメモリ・リード・リクエストのTLPです。
それに対して
「4A000002 02000008 00001608 F43D85EE 8526871B」というコンプリーションを返しています。
最後の2DWのF43D85EE 8526871Bというのが応答したパケットに含まれるデータです。

このように、2DWのコンプリーションも返せます。

また、ルートコンプレックスからCombied Writeで送られてきた16DWのデータの塊も、問題なく受け入れられています。
Sp6pciememwr64

このような感じで、長いデータ転送ができるようになったので、FPGA内に64kバイトのメモリを実装し、メモリ空間の読み書きテストを行いました。
Sp6_pcie_test

エラーなく転送できていることが確かめられ、Writeは約120MBytes、Readは約1.8MBytesという結果が出ました。Readが遅いのはPIOモードであるためです。
あと2~3日じっくり取り組めば、DMAや割り込みまで移植できそうです。

PCI Expressが自由自在に使えるようになるまで、あと少しです。

|

« PCI Express転送テストアプリとデバイスドライバを更新 | トップページ | ノートPC「Eee PC S101」を自力で修理 »

コメント

コメントを書く



(ウェブ上には掲載しません)




« PCI Express転送テストアプリとデバイスドライバを更新 | トップページ | ノートPC「Eee PC S101」を自力で修理 »