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 というのは、以下をそのまま使っている。
とりあえず、シンプルに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 $@
でもこれでは実用には全く耐えられないので、どうにかしていろんなライブラリを動かす必要がある。この部分はまだ要調査だ...