ZED BoardでPLを自作した場合のDMAのやりかた
ZED Boardで、AXI HighPerformance Portを通じて、PLからPSのDDR3 SDRAMにアクセスするハードウェアを以前作りました。
HPポートを通じてPLからDDR3にアクセスすれば、DMAができるわけです。
OSを使わないStandAloneなプログラムで動いている場合はそれほど難しくなかったのですが、Linuxが動かそうとしてカスタマイズしたPLのBitStreamを埋め込んだboot.binで起動しようとすると、Linuxがパニックを起こしてハングしてしまいます。
で、ついに、当社の優秀なスタッフが、ZED BoardでのDMAを実現してくれました。そのやり方を簡単にまとめると・・
- 基本的に、ZED BoardのDeviceTree(dtbファイル)を逆変換してソース(dtsファイル)を作り、編集してdtbに変換することでカスタマイズDeviceTreeを作る。
- PLをカスタマイズしたBitStreamでLinuxを起動させようとすると、起動中にqspiがどうの、というメッセージが出て止まってしまう。これを回避するには、devicetreeの、ps7_qspi_0にbus-num = <0>;を追加すればOK。
- ファイルシステムのエラーを回避するには、bootargsにroot=/dev/ram rw initrd=0x800000,8M earlyprintk rootfstype=ext4 rootwait devtmpfs.mount=0を追加する。
- bootargsにmem=128Mを追加する。これで、Linuxが使用するメモリを128MBに抑えるることができ、0x08000000~0x1fffffffはLinuxの管理外になるので、FPGAから自由に使用できるようになる。
- AXIスレーブとして作った制御レジスタがある場合、DeviceTreeからaxi_ext_slave_conn…(0xB8800000~)のような記述は削除する。これを削除しないと、キャッシュが効いてしまうので正しくアクセスできない。
- ZED Boardでは物理アドレス0x08000000~0x1fffffffにはDDR3 SDRAMが配置されている。LinuxのプログラムからDDR3を参照するにはmmap()関数を使って、まずこの領域の仮想アドレスを取得する。
なお、mmap()の前に、open()で/dev/memを開く。メモリの読み書きの同期にはmsync()を使う。最後にmunmap()で解放すること。
こんな手順をふむことで、LinuxからFPGAのPLにアクセスし、DMAを行うことができるようになりました。
これで、Linuxのネットワーク機能と、FPGAの高速な演算を使える環境が整いました。
最近のコメント