View on GitHub

memo

CL_DRAM_DMA のメモ

実行方法

インスタンスの準備やリポジトリのclone、AFIの生成方法等は、AWS EC2 F1インスタンスを使ってみると同じ。

F1インスタンスでの作業

リポジトリのcloneまで終わったら、以下の手順を実施します。

XOCLドライバのアンインストール

テストプログラムの実行には、XDMAドライバが必要。しかし、FPGA Developer AMIのversion 1.5.0以降では、XOCLのドライバがインストールされていて、XDMAドライバが動かない。(と言うより、XDMAはもはやサポートされていない…) ここでは、無理矢理動かすため、XOCLドライバを取り除いてから、XDMAドライバをインストールする。

XOCLドライバがインストールされているかをチェックする。以下のようにxoclが表示されればインストールされています。

$ lsmod | grep xocl
xocl                  805140  0 
drm                   456166  5 ttm,xocl,drm_kms_helper,cirrus
libcrc32c              12644  2 xfs,xocl

XOCLドライバをアンインストールします。

sudo rmmod xocl

XDMAドライバのインストール

XOCLドライバをビルド、インストールします。

ドライバのビルドに必要なツールをインストールします。

sudo yum groupinstall "Development tools"
sudo yum install kernel kernel-devel

カーネルがインストールされたら、再起動します。

sudo shutdown -r now

再起動後に、以下のようにドライバをビルドします。

cd $AWS_FPGA_REPO_DIR/sdk/linux_kernel_drivers/xdma
make

ドライバをインストールします。

sudo make install

ドライバをロードします。(OSの再起動は不要です)

sudo modprobe xdma

ドライバがロードされているかは以下のように確認します。

$ lsmod | grep xdma
xdma                   72503  0 

テストプログラムの実行

テストプログラムの実行は以下の通り。

cd $HDK_DIR/cl/examples/cl_hello_world
export CL_DIR=$(pwd)
cd $CL_DIR/software/runtime/
make all
sudo ./test_dram_dma

テストプログラムの内容

初期化

dma_example

FPGAに載っている4つのDDR4 SDRAMに16MBのランダムなデータを書き込んで、読み出して、差がないかをチェック

interrupt_example

FPGAのレジスタに、fpga_pci_pokeで割込み番号を指定して書き込むと、FPGA側からPCIe MSI-X(Message-Signaled Interrupt - X)割込みがインスタンス側に発生するようになっている。

一連の流れは概略は以下の通り。変数の宣言やエラー処理は省略

    // pollシステムコールで受け取るファイル・ディスクリプタ
    struct pollfd fds[1];
    // PCIスロットを指定してデバイス番号を取得
    fpga_pci_get_dma_device_num(FPGA_DMA_XDMA, slot_id, &device_num)
    // 割込みを受けるデバイスファイル名を生成
    sprintf(event_file_name, "/dev/xdma%i_events_%i", device_num, interrupt_number);
    // FPGAに接続
    fpga_pci_attach(slot_id, pf_id, bar_id, fpga_attach_flags, &pci_bar_handle);
    // デバイスファイルを開いて、pollのファイル・ディスクリプタを設定
    fd = open(event_file_name, O_RDONLY))
    fds[0].fd = fd;
    fds[0].events = POLLIN;
    // FPGAのレジスタに値を書き込む
    fpga_pci_poke(pci_bar_handle, interrupt_reg_offset , 1 << interrupt_number);
    // 割込みイベントを待つ
    rd = poll(fds, num_fds, poll_timeout);
    if((rd > 0) && (fds[0].revents & POLLIN)) {
        // イベントを読み込み
        rc = pread(fd, &events_user, sizeof(events_user), 0);
	// FPGA側に割込みのクリアを指示
	fpga_pci_poke(pci_bar_handle, interrupt_reg_offset , 0x1 << (16 + interrupt_number) );
    }

axi_mstr_example

FPGA側の構成

cl_dram_dma.svファイルのcl_dram_dmaがTopモジュール。この中にDRAMアクセスや割込みの実例のモジュールがインスタンス化されている。

DRAMアクセス

割込み

以下の流れで処理が行われる

  1. F1インスタンスのテストプログラムからの0xd00番地のレジスタ書き込みが、sh_ch_oclのポートから伝達
  2. cl_ocl_slv.svファイルのcl_ocl_slvモジュールが、レジスタ書き込みを受け付けて、int_tst_cfg_busのポート経由でcl_int_slvに割込みの発生を要求
  3. cl_int_slv.svファイルのcl_int_slvと、cl_int_tst.svファイルのcl_int_tstが、F1インスタンス側に割込みを要求