fpgaアクセラレータの作り方 (ibm power+capi編)

Post on 16-Apr-2017

1.144 Views

Category:

Devices & Hardware

1 Downloads

Preview:

Click to see full reader

TRANSCRIPT

FPGAアクセラレータの作り方

IBM POWER+CAPI編

@Vengineer2016/10/7

Vengineer DEATH

無限ゲームのなか

いつものように、

よろしくお願いします。

@Vengineer に居ます

Overview

http://www.nallatech.com/wp-content/uploads/IBM_CAPI_Users_Guide_1-2.pdf

一見すると、CPUとFPGAだがFPGAの中に

ある

PSLと

POWER8の中にある

CAPPが重要

IBM CAPIとは

Coherent Accelerator Processor Interface

The Coherent Accelerator Processor Interface (CAPI) is a general term for the infrastructure of attaching acoherent accelerator to an IBM POWER® system. The main application is executed on the host processorwith computation-heavy functions executing on the accelerator. The accelerator is a full peer to the hostprocessor, with direct communication with the application. The accelerator uses an unmodified effectiveaddress with full access to the real address space. It uses the processor’s page tables directly with pagefaults handled by system software.

Coherent Accelerator Processor Interface

http://www.nallatech.com/wp-content/uploads/IBM_CAPI_Users_Guide_1-2.pdf

POWER8(CPU)は、MMUで仮想アドレス => 物理アドレスにしてメモリにアクセス

POWER8とAcceleratorのメモリ共有

Acceleratorは、PSL/PCIe/CAPPで仮想アドレス => 物理アドレスにしてメモリにアクセス

http://openpowerfoundation.org/wp-content/uploads/2015/03/Finamore-Nick_OPFS2015_Altera_031215_final.pdf

Host Memory & Device Memory

Altera SDK for OpenCL

http://openpowerfoundation.org/wp-content/uploads/2015/03/Finamore-Nick_OPFS2015_Altera_031215_final.pdf

Coherent Memory

Xeon - QPI − FPGACCI-extended

コピー不要 &デバイスドライバ不要

メモリ移動 メモリ移動終了待ち起動

終了待ち起動

http://www.nallatech.com/wp-content/uploads/Ent2014-CAPI-on-Power8.pdf

Hardware

AFU

POWER8とFPGAの関係

CAPP

PCIe FPGA

PHB : PCIe Host BridgeCAPP : Coherently Attached Processor Proxy

PSL : Power Service LayerAFU : Accelerator Function Unit

PHB

CPU

POWER8

PSL

AFU

PSL : POWER Service Layer

CAPP

PCIe FPGA

PSLは、IBMが開発

CAPI対応FPGAボードベンダから提供される (IBMから供給)

PHB

CPU

POWER8

PSL

PSL : POWER Service Layer

The PSL provides the translation and interrupt services that the AFU needs.

This is what the kernel interacts with. For example, if the AFU needs to read a particular effective address, it sends that address to the PSL, the PSL then translates it, fetches the data from memory and returns it to the AFU. If the PSL has a translation miss, it interrupts the kernel and the kernel services the fault. The context to which this fault is serviced is based on who owns that acceleration function.

https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/plain/Documentation/powerpc/cxl.txt

AFU

AFU : Accelerator Function Unit

CAPP

PCIe FPGA

AFUは、ユーザが開発

HDL(Verilog HDL/VHDL)でなく、HLSなどを使ってC/C++でも可能

PHB

CPU

POWER8

PSL

Software

AFU

libcx

PCIe FPGA

Applicationは、libcxl (ユーザ空間) API =>Linux CXLデバイスドライバ経由でFPGAのAFUにアクセスする

FPGA(AFU)独自のデバイスドライバは不要

PSL

CXL

Application

POWER8

libcxl

Coherent Accelerator Interface

https://github.com/ibm-capi/libcxl

CXL : linux device driver https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/plain/Documentation/powerpc/cxl.txt

libcxl API

open : デバイスのオープン

ioctl : CXL_IOCTL_START_WORK

CXL_IOCTL_GET_PROCESS_ELEMENT

mmap : mmio空間へのアクセス

read : AFUからのイベントを読み込む

AFU

Application

PCIe FPGA

Applicationは、libcxl (ユーザ空間) API =>Linux CXLデバイスドライバ経由でFPGAのAFUにアクセスする

FPGA(AFU)独自のデバイスドライバは不要

PSL

CXL

Application

POWER8

libcxl

Applicationのテンプレートコード

// AFUの確認

struct cxl_afu_h *afu_h = cxl_afu_next(NULL);// AFUを獲得

afu_h = cxl_afu_open_h(afu_h,CXL_VIEW_DEDICATED);// AFUの起動

cxl_afu_attach(afu_h, (uint64_t) wed);// 必要ならMMIOをマップ

cxl_mmio_map(afu_h, CXL_MMIO_BIG_ENDIAN);

// ここで何かをやる

cxl_mmio_unmap(afu_h); // MMIOをアンマップ

cxl_afu_free(afu_h);  // AFUを開放

CAPI Solution FLow

http://www.nallatech.com/wp-content/uploads/Ent2014-CAPI-on-Power8.pdf

本題のHDLシミュレーション環境

PSLSE ModelSim ASE 10.4d

Power Service Layer Simulation Engine

PLITCP/IP

AFU (HDL)TCP/IP

PSLSE用のlibclxには、

一部実装されていない関数がある

https://github.com/ibm-capi/pslse

Application

libcxl

githubから環境をダウンロード

% git clone https://github.com/ibm-capi/pslse

% lsNOTICES afu_driver pslseQUICK_START common sample_appREADME debug testSIMULATOR_SETUP libcxl vcs_include

% cd afu_driver

% lssrc verilog

ModelSim ASEの環境設定

% export ALTERA_HOME={ModelSim ASEのディレクトリ}

% export VPI_USER_H_DIR=${ALTERA_HOME}/include

VPI_USER_H_DIRは、利用するインクルードファイルの場所を指定する

DPI-Cライブラリのビルド

% cd src ; BIT32=y make [CC] afu_driver.o [CC] afu_driver.d [SED] afu_driver.d [CC] psl_interface.o [CC] psl_interface.d [SED] psl_interface.d [CC] veriuser.sl [CC] libdpi.so

ModelSim ASE 10.4d (Linux版)は32ビット版なのでマクロ(BIT32)を有効にする必要があるREADME.32bitを参照のこと

ライブラリ

HDLのコンパイル

% cd verilog// ライブラリの生成% vlib work// WORKライブラリへマッピング% vmap work// トップテストベンチをWORKライブラリにコンパイル% vlog -sv top.v-- Compiling module top

Top level modules: topEnd time: 14:13:01 on Jul 24,2016, Elapsed time: 0:00:00Errors: 0, Warnings: 0

トップテストベンチ

シミュレーション開始

% vsim -c -L afu -sv_lib ../src/libdpi top ¥ -do "run -all"# Loading work.top# ** Error: (vsim-19) Failed to access library 'afu' at "afu".# No such file or directory. (errno = ENOENT)# ** Error: (vsim-3033) top.v(699): Instantiation of 'afu' failed. The design unit was not found.# Time: 0 ps Iteration: 0 Instance: /top File: top.v# Searched libraries:# ** Error: (vsim-19) Failed to access library 'afu' at "afu".# No such file or directory. (errno = ENOENT)# /home/uip/ibm-capi/pslse/afu_driver/verilog/work# Error loading designError loading design# End time: 14:18:35 on Jul 24,2016, Elapsed time: 0:00:00# Errors: 3, Warnings: 0

work.topをロード中にafuが無いというエラーが発生

( ̄Д ̄;) ガーン

AFUのサンプルがない

いつものように

Google君にきいた

CAPIStreaming Framework

capi-streaming-framework

AFU framework for streaming applications with CAPI connected FGPAs.

% git clone https://github.com/mbrobbel/capi-streaming-framework.git

% cd capi-streaming-framework

% git submodule update --init

http://slides.com/mbrobbel/capi-streaming-framework

PSLSE ModelSim ASE 10.4d

AFUは、VHDLで実装されている

Applicationmemcpy

PLITCP/IP

Top (SystemVerilog)AFU (VHDL)

libclx

TCP/IP

ModelSim ASE 10.4d では、

Verilog HDL(SystemVerilog)/VHDLの混在シミュレーションが出来るよ

http://blogs.yahoo.co.jp/verification_engineer/69928166.html

pslse Build

% export VPI_USER_H_DIR=${ALTERA_HOME}/include

% make pslse-build

makeコマンドが、(cd sim/pslse/afu_driver/src && make clean && BIT32=y make)を実行して、

libvpi.so, libcxl.a, libcxl.so を作ってくれた

最初からこちらでやればいいんだった。orz

pslse Buildでのエラー

[CURL ../common/misc/cxl.h] [CC] libcxl.oIn file included from libcxl.h:21:0, from libcxl.c:32:../common/misc/cxl.h:140:2: error: unknown type name 'u8' u8 data[]; ^make[1]: *** [libcxl.o] Error 1

sim/pslse/libcxl/Makefile.vars で、

CFLAGS += -Wall -Wunused-but-set-variable -I$(CURDIR) -I$(COMMON_DIR) -fPIC

CFLAGS += -Du8=__u8を追加して対応した

Application Build

% make sim-buildmkdir -p host/app/sim-buildc++ host/app/src/example.cpp -o host/app/sim-build/example sim/pslse/libcxl/libcxl.a -O3 -Wall -m64 -Isim/pslse/common -Isim/pslse/libcxl -lrt -lpthread -D SIM

こちらも作ってくれた。orz

Application Buildでのエラー

In file included from sim/pslse/libcxl/libcxl.h:21:0, from host/app/src/example.cpp:9:sim/pslse/common/misc/cxl.h:140:2: error: 'u8' does not name a type u8 data[]; ^make: *** [sim-build] Error 1

Makefile で、

CFLAGS = -O3 -Wall -m64を

CFLAGS = -O3 -Wall -m64 -Du8=__u8にて、対応した

sim/pslse/libcxl/Makefile内の

http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/plain/include/uapi/misc/cxl.h

http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.gi

t/plain/include/uapi/misc/cxl.h ?h=v4.7

と、Linux v4.7からコードを獲得するようにすることでエラーが無くなる

cxl.hのエラーの回避

Simulation Run

% make vsim-run <= #1 HDL Simulationcd sim && vsim -do vsim.tcl……# Compiling top levelModelSim> s    <= シミュレーションを開

……# Loading ./pslse/afu_driver/src/veriuser.slで待ちになるので、違うターミナルで

# make pslse-run <= #2 PSLSE

もう一つ違うターミナルで

# make sim-run ARGS=128 <= #3 Application

3つのプロセスで実現

AFU is done.memcpy successful.

INFO:127.0.0.1 client disconnect from afu0.0 context 0INFO:Sending reset to AFUDEBUG:afu0.0:JOB code=0x80 ea=0x0000000000000000DEBUG:afu0.0:JOB doneINFO:Stopping clocks to afu0.0

HDL Simulation EnvironmentModelSim ASE 10.4d

PSLSE

Application

Application

Application : memcpy

struct cxl_afu_h *afu;afu = cxl_afu_open_dev((char*) (DEVICE));cxl_afu_attach(afu, (__u64) wed0);cxl_mmio_map(afu, CXL_MMIO_BIG_ENDIAN);

// ポーリングでAFUの終了待ちwhile (!wed0->status) { cxl_mmio_read64(afu, MMIO_ADDR, &rc);}

cxl_mmio_unmap(afu_h); // MMIOをアンマップ

cxl_afu_free(afu_h);  // AFUを開放

capi-streaming-framework/host/app/src/example.cpp

cxl_afu_open_dev

#define DEVICE "/dev/cxl/afu0.0d"

// 戻り値のafuは、ファイル識別子のようなもの

struct cxl_afu_h *afu;

// cxl_afu_open_dev関数でデバイスをオープンする

afu = cxl_afu_open_dev ((char*) (DEVICE));

https://github.com/ibm-capi/pslse/wiki/Programming-with-libcxl

cxl_afu_attachstruct wed *wed0 = NULL;posix_memalign ((void **) &(wed0), CACHELINE_BYTES, sizeof(struct wed));wed0->status = 0;wed0->size = copy_size;wed0->source = source;wed0->destination = destination;

// デバイスと接続し、動作を開始

cxl_afu_attach(afu, (__u64) wed0);

https://github.com/ibm-capi/pslse/wiki/Programming-with-libcxl

cxl_afu_attach

struct wed { __u8 volatile status; // 7 downto 0 __u8 wed00_a; // 15 downto 8 __u16 wed00_b; // 31 downto 16 __u32 size; // 63 downto 32 __u64 *source; // 127 downto 64 __u64 *destination; // 191 downto 128 __u64 wed03; // 255 downto 192 …. __u64 wed15; // 1023 downto 960};

https://github.com/ibm-capi/pslse/wiki/Programming-with-libcxl

cxl_mmio_map// MMIOをマップする

cxl_mmio_map (afu, CXL_MMIO_BIG_ENDIAN)) < 0);

https://github.com/ibm-capi/pslse/wiki/Programming-with-libcxl

ポーリングによる処理待ち

uint64_t rc;

// ポーリングによる処理待ち

while (!wed0->status) { cxl_mmio_read64(afu, MMIO_ADDR, &rc); printf("Response counter: %lu\n", rc);}

https://github.com/ibm-capi/pslse/wiki/Programming-with-libcxl

参考:cxl_mmio_xxxx

64ビットアクセスと32ビットアクセス

cxl_mmio_read64(afu, 0, &data64)cxl_mmio_write64(afu, 8, data64)

cxl_mmio_read32(afu, 20, &data32)cxl_mmio_write32(afu, 28, data32)

https://github.com/ibm-capi/pslse/wiki/Programming-with-libcxl

参考:割り込みによる処理待ち

struct cxl_event intr;

// ブロッキング処理の場合

cxl_read_event(afu, &intr); <= ここがブロッキング

handle_event(intr); // interrupt handler

while (cxl_pending_event(afu)) {

cxl_read_event(afu, &intr);

handle_event(intr); // interrupt handler

}

https://github.com/ibm-capi/pslse/wiki/Programming-with-libcxl

参考:割り込みによる処理待ち

struct cxl_event intr;

// ノン・ブロッキング処理の場合

while (cxl_pending_event(afu)) {

cxl_read_event(afu, &intr);

handle_event(intr); // interrupt handler

}

https://github.com/ibm-capi/pslse/wiki/Programming-with-libcxl

cxl_mmio_unmap/cxl_afu_free

// MMIOのアンマップ

cxl_mmio_unmap (afu);

// デバイスの開放

cxl_afu_free (afu);

https://github.com/ibm-capi/pslse/wiki/Programming-with-libcxl

libcxl => pslse

libcxl <=> pslse

cxl_afu_open_dev _pslse_connect _pslse_open

_psl_loop

HDL Simulationサーバー機能

capi-streaming-framework/sim/pslse/libcxl/libcxl.c

cxl_afu_attachcxl_mmio_attachcxl_mmio_readxxx

pthread生成

_pslse_loop

// コマンド待ちのループ処理

while (afu->opened) { _delay_1ms(); // Send any requests to PSLSE over socket if (afu->int_req.state == LIBCXL_REQ_REQUEST) _req_max_int(afu); if (afu->attach.state == LIBCXL_REQ_REQUEST) _pslse_attach(afu); if (afu->mmio.state == LIBCXL_REQ_REQUEST) {

capi-streaming-framework/sim/pslse/libcxl/libcxl.c

_pslse_loop続き

switch (afu->mmio.type) { case PSLSE_MMIO_MAP: _mmio_map(afu); break; case PSLSE_MMIO_WRITE64: _mmio_write64(afu); break; case PSLSE_MMIO_WRITE32: _mmio_write32(afu); break; case PSLSE_MMIO_READ64: case PSLSE_MMIO_READ32: /*fall through */ _mmio_read(afu); break; Default: break; }

capi-streaming-framework/sim/pslse/libcxl/libcxl.c

Top Testbench

Simulation : Top Testbench

top

AFUPLIベースモデル

afu_driverpslse

libcxl

App

capi-streaming-framework/sim/pslse/afu_driver/verilog/top.v

Top Testbenchの続き

PLIベースモデル:afu_driverの実態 => PLI関数

$afu_init; // サーバー機能の初期化

$register_clock(...); // クロックの登録

$register_control(...); // 各信号線の登録

$register_mmio(...);$register_command(...);$register_rd_buffer(...);$register_wr_buffer(...);$register_response(...);

PLIベースモデル : afu_driver//サーバー機能の初期化

$afu_init; => afu_init

// クロックの登録

$register_clock(); => register_clock

// 各信号線の登録

$register_control(); => register_control$register_mmio(); => register_mmio$register_command(); => register_command$register_rd_buffer(); => register_rd_buffer$register_wr_buffer(); => register_wr_buffer$register_response(); => register_response

capi-streaming-framework/sim/pslse/afu_driver/src/afu_driver.c

AFU

AFU : memcpy RTL (VHDL)

AFUFRAME

ControlMMIO

DMA CU

CAPI Streaming Framework

capi-streaming-framework/accelerator/rtl

PSL

CU : memcpy

CU

FIFO

FSM

cu_in cu_out

type cu_in is record cr : cr_in; start : std_logic; wed : wed_type; id : unsigned(DMA_ID_WIDTH - 1 downto 0); read : dma_read_response; write : dma_write_response;end record;

type cu_out is record done : std_logic; read : dma_read_request; write : dma_write_request;end record;

capi-streaming-framework/accelerator/rtl/cu.vhd

おしまい

top related