Intel PACでstreaming_dma_afuを試してみる

Pocket

Intel PACの開発環境 inteldevstack に同梱されているサンプルのstreaming_dma_afuを試してみました。このサンプルは、

のように、PAC上のロジックに対してストリームで入出力するサンプルです(画像はサンプルのREADME.txtより・クリックで拡大)。

合成

合成は、以下の手順です

$ cd ${OPAE_PLATFORM_ROOT}/hw/samples/streaming_dma_afu
$ afu_synth_setup --source hw/rtl/filelist.txt build_synth
$ ${OPAE_PLATFORM_ROOT}/bin/run.sh

これで、streaming_dma_afu.gbs ができあがります。実機で動かすには、PACSignが必要なので

$ PACSign PR -t UPDATE -H openssl_manager \
             -i streaming_dma_afu.gbs \
             -o streaming_dma_afu_unsigned.gbs

とします。できあがったら fpgaconf でFPGAをコンフィギュレーション。

$ fpgaconf streaming_dma_afu_unsigned.gbs

動作確認

ソフトウェア側をコンパイルして動作を確認します。

$ cd ../sw
$ make

できあがった fpga_dma_st_test を実行して動作が確認できます。

$ ./fpga_dma_st_test -l on -s 1024000 -p 102400 -t fixed
Memory to Stream BW = 2805 MBps, Stream to Memory BW = 3572 MBps

fpga_dma_st_testをオプションなしで実行すると、設定可能なオプションを確認することができきます。

デザインを眺めてみる

合成した作業ディレクトリ中にある .qpf ファイルをQuartusで開くと、デザインを眺めることができます(画像はクリックで拡大)。

dcp_top→fpga_top→inst_green_bs→ccip_std_afu→afu_instとたどると、Platform Designerで作られたthe_streaming_dma_test_systemという名前のstreaming_dma_test_systemモジュールのインスタンスが見つかります。

次のスクリーンショットは、ダブルクリックしてPlatform Designerで開いたところです。

Pattern checkerはm2s_custom_pattern_checker、s2m_custom_pattern_checherという名前の、それぞれcustom_pattern_checkerとcustom_pattern_generatorモジュールのインスタンスです。Platform DesignのSystem Viewを観察してみると、m2s_dma_bbb/s2m_dma_bbbというモジュールを介して、データ供給・出力されることが確認できます。

また、one_to_two_streaming_demultiplexer/two_to_one_streaming_multiplexerを介してDecimator(streaming_decimator)でループバックされています。

なお、custom_pattern_generatorのカーネルは

${OPAE_PLATFORM_ROOT}/hw/samples/streaming_dma_afu/hw/rtl/QSYS_IPs/custom_pattern_generator/mtm_custom_pattern_generator.v

に、custom_pattern_checkerのカーネルは、

${OPAE_PLATFORM_ROOT}/hw/samples/streaming_dma_afu/hw/rtl/QSYS_IPs/custom_pattern_checker/mtm_custom_pattern_checker.v

に、streaming_decimatorのカーネルは、

${OPAE_PLATFORM_ROOT}/hw/samples/streaming_dma_afu/hw/rtl/QSYS_IPs/avst_decimator/avst_decimator.sv

に、それぞれあります。

ソフトウェアの構成

サンプルソフトウェアは以下のように構成されています。

  • sw/fpga_dma_st_test.cpp
    • main関数.引数の解析(parse_args)
    • do_action で処理を開始
  • sw/fpga_dma_st.cpp
    • MMIOWrite64Blk/MMIOWrite32Blk/MMIORead64Blk/MMIORead32Blk
    • dispatcherWorker
    • completionWorker
    • fpgaDMAOpen/fpgaDMAClose/fpgaGetDMAChannelType/fpgaDMATransferInit/fpgaDMATransferReset/fpgaDMATransferDestroy
    • fpgaDMATransferSetSrc/fpgaDMATransferSetDst/fpgaDMATransferSetLen/fpgaDMATransferSetTransferType/
      • pthread_mutex_lockとってfpga_dma_transfer_t方の引数のパラメタをアップデート
    • fpgaDMATransferSetTxControl/fpgaDMATransferSetRxControl/fpgaDMATransferSetTransferCallback/fpgaDMATransferSetLast/fpgaDMATransferGetBytesTransferred/fpgaDMATransferCheckEopArrived
    • fpgaDMATransfer
      • dma->ingress_queue.push(sw_desc) でDMA処理を実行
    • fpgaDMAInvalidate
      • pthread_mutex_lockとってfpga_dma_transfer_t方の引数のパラメタをアップデート
  • sw/fpga_dma_st_test_utils.cpp
    • do_action – 実際の処理のエントリ関数
      • non_loopback_test/loopback_testを呼び出す
    • loopback_tset
      • pthread_createでm2sworkerとs2mworkerを起動.各スレッドが終了するまで待つ(pthread_join)
    • non_loopback_test
      • config->directionによって m2sworker か s2mworker を呼び出す
    • stomCb/mtosCb – バイト数のカウント
    • m2sworker, s2mworker
      • fpgaDMATransferSetSrc, fpgaDMATransferSetDst, fpgaDMATransferSetLen, fpgaDMATransferSetTransferTypeでDMAセット
      • m2sworker: fpgaDMATransferSetTxControl(transfer, TX_NO_PACKET/GENERATE_SOP/GENERATE_EOP/TX_NO_PACKET) で 送信
      • s2mworker: fpgaDMATransferSetRxControl(transfer, rx_ctrl); で 受信
  • sw/fpga_pattern_checker.cpp
    • start/stop_checker, wait_for_checker_completeでpacket_generaterの制御
      • fpgaReadMMIO32/fpgaWriteMMIO32でレジスタの読み書きをして制御する
  • sw/fpga_pattern_gen.cpp
    • start/stop_generator, wait_for_generator_completeでpacket_generaterの制御
      • fpgaReadMMIO32/fpgaWriteMMIO32でレジスタの読み書きをして制御する
  • sw/fpga_dma.h
    • fpgaDMAXXX系などの関数のプロトタイプ
  • sw/fpga_dma_st_common.h
    • debug_print/error_printなどの定義
  • sw/fpga_dma_st_internal.h
    • FPGA制御関連のdefineや構造体
  • sw/fpga_dma_st_test_utils.h
    • fpga_dma_st_testで使う定数などの定義
  • sw/fpga_dma_types.h
    • DMA転送用の構造体の定義
  • sw/fpga_pattern_checker.h
    • pattern_checkerのレジスタのベースアドレス,レジスタ読み書き用の構造体
  • sw/fpga_pattern_gen.h
    • pattern_generatorのレジスタのベースアドレス,レジスタ読み書き用の構造体
  • sw/x86-sse2.h
    • x86 SSE2でデータのアライメントを取るためのヘルパー関数のプロトタイプ
  • sw/x86-sse2.S
    • x86 SSE2でデータのアライメントを取るためのヘルパー関数の実装(アセンブラ)