« Virtex-4&PowerPCの書き込みアルゴリズム改善 | トップページ | DMAによる長いメモリライトを実装 »

2010.03.03

PCI ExpressのDMA実装

ようやく重い腰を上げて、PCI ExpressコアにDMAと割り込みの実装をはじめました。
実は、昨年3月にも少し作業していたのですが、いろいろと不可解な現象にあたって途中であきらめていたようです。

DMAを実装する最大の理由は、FPGA→PC方向への転送速度の改善です。PC→FPGA方向はDMAを使わなくても、工夫次第で190MBytes/secくらい出ています。しかし、FPGA→PC方向が遅くて、DMAが必要ということになったわけです。

さて、今あるコアのDMAの問題点を洗い出してみると、
① DMAのバッファ用にアロケートするメモリが4096バイトしか取っていない
② MaxPayloadSizeやRCBにあわせて転送を細切れにすることができない
③ DMAの完了を知る術がない
④ DMAで送ってくるデータを入れる専用のポートがない

-----
①の問題。
DMAのバッファをどこに確保するかというのは、奥が深いテーマのようです。ユーザアプリケーションで使っているバッファ(つまりmallocとかで取ったやつ)の物理アドレスを調べて、そこめがけて転送するのがベストですが、何かと難しいようです。
しかし、カーネルモードでDMA用の安全なバッファを取るのが一番簡単ですが、安全なバッファとユーザバッファの間でデータをコピーしなければいけないので、DMAのメリットが出ません。ユーザのバッファをめがけてDMAする方法を、私自信、もっと勉強するしかないですね。

②の問題。
FPGA内にDMAコントローラを内蔵させることにしますま。数メガバイトとか数百Mバイトといったサイズの転送を128バイト単位で細切れにしなければなりません。スキャッタギャザーにも対応させたいです。
ユーザ回路とPCI Expressコアとの間には、やはりFIFOが1段くらいは必要になりそうです。
この実装は明日。

③の問題
やっぱり割り込みを実装するしかないですね。

④の問題
特電PCI ExpressコアにDMA用の制御信号を増設します。
component pciecore is Port (
  ・・ 中略 ・・
dma_cfg_c : in std_logic_vector(15 downto 0);
dma_sysaddr_i : in std_logic_vector(31 downto 0); -- PC内メインメモリの物理アドレス
dma_lcladdr_i : in std_logic_vector(31 downto 0); -- ローカル(コア上)のアドレス
dma_length_i : in std_logic_vector(9 downto 0); -- DW単位
dma_wr_req_i : in std_logic; -- DMA要求(FPGA->PC)
dma_wr_ack_o : out std_logic; -- DMA応答
dma_rd_req_i : in std_logic; -- DMA要求(PC->FPGA)
dma_rd_ack_o : out std_logic; -- DMA応答
dma_wrdata_i : in std_logic_vector(31 downto 0); -- 書き込みデータ
dma_rddata_o : out std_logic_vector(31 downto 0); -- 読み出しデータ
dma_addr_o : out std_logic_vector(31 downto 0);
dma_length_o : out std_logic_vector(31 downto 0);
dma_wdata_o : out std_logic_vector(31 downto 0);
dma_be_o : out std_logic_vector(3 downto 0);
dma_dvalid_o : out std_logic; -- DMA受信データ有効
dma_dreq_o : out std_logic; -- DMA送信データ要求
  ・・ 中略 ・・
);
これだけ作っておけば足りるでしょう。

---

さて、テストしてみます。まず、PC→FPGA方向への転送。
FPGAの中からPCのメインメモリに対して読み出しリクエストを行っています。

Pcie_dma1

FPGAがリードリクエストして、PCが応答します。この場合、データを何バイト単位で返すかはPC内のチップセットが決めますが、やはり64バイト単位に細切れにされていました。

CombinedWriteの時と違うのは、MemRdに対するCompletionとしてデータが送られてきている点です。
この速度は190MBytes/secも出ていました。PCI Expressの帯域は200MBytes/secなので、良い結果でしょう。
しかし、CombinedWriteの時と速度は変わりません。

次に、FPGA→PC方向の転送。
Pcie_dma2

おおっ、夢にまで見たバースト転送。このデータは、ちゃんとPC内のバッファに蓄えられていました。

しかし、まだ128バイトまでのDMAしかできません。128バイトを超えたときどのくらいの速度が出るかは、明日、試してみることにします。

DMAの実装は、FPGAだけではなく、ドライバもセットで作っていかなければならないから大変です。

|

« Virtex-4&PowerPCの書き込みアルゴリズム改善 | トップページ | DMAによる長いメモリライトを実装 »

コメント

コメントを書く



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




« Virtex-4&PowerPCの書き込みアルゴリズム改善 | トップページ | DMAによる長いメモリライトを実装 »