FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

C++で記述された軽量CNN実装 mojo-cnn 試行 (4. RISC-V on FPGAのデバッグ)

f:id:msyksphinz:20170925003926p:plain

FPGAでCNNのプログラムを動かそうとしたのだが、C++のコードをそのままRISC-Vでコンパイルして走らせてもどうもうまく行かない。 そもそもの問題だが、例えばRISC-V on FPGAで何かを動かしたい場合、printfなどは独自のsyscalls.c を使ってPS (=ARM)に表示させるように改造しなければならない。 つまり、std::cout などは現状では未対応というように考えればよい?

つまり、std::cout とすると一応spike で動かすことはできるのだが、これをどのようにしてFPGAで動かすプログラムとしてコンパイルしなおせばよいのか不明なのだ。むう。 ただしspikeでstd::coutを動かすことができているので、出来ないはずはない。spikeがstd::coutをどのように処理しているのか要調査だな...

syscalls.c というのは、以下をそのまま使っている。

github.com

とりあえず、シンプルにriscv64-unknown-elf-g++ を使って簡単なC++のコードをコンパイルして、RISC-V on FPGAで動かしてみようとしたのだが、いろんなライブラリを削除してコンパイルしているため結構つらい。syscalls.cに載っていない関数は基本的に使えないし、C++独特のname manglingに対応させるために色々とてこづった。

結果的に、以下のようなtest.cpp を用意して(まあほぼCのコードなのだが)、g++でコンパイルし、gccコンパイルしたcrt.Sとsyscalls.c とくっつけてバイナリを作ることはできた。

// #include <iostream>
#include <stdio.h>

int main ()
{
  printf ("Hello World\n");

  return 0;
}
test_ideal: test.cpp syscalls.o crt.o makefile
        $(CC) $(CFLAGS) -mcmodel=medany -fno-builtin-printf -static -std=gnu99 -O2 -ffast-math -fno-common -nostdlib -nostartfiles -ffast-math -lgcc $< crt.o syscalls.o -o $@ -T ./common/test.ld

crt.o: ./common/crt.S
        $(CC)  -c $(CFLAGS) ./common/crt.S

syscalls.o: common/syscalls.c
        $(CC) $(CFLAGS) -mcmodel=medany -c $< -o $@
f:id:msyksphinz:20180521015029p:plain
図. C++のコード(というかほぼC)をRISC-V向けにコンパイルしてRocket-Chipで動かした図

でもこれでは実用には全く耐えられないので、どうにかしていろんなライブラリを動かす必要がある。この部分はまだ要調査だ...