FPGAでFPUを実装して浮動小数点演算するっ。ALTERA(現Intel)のFPGA使うならALTFPってのがあるけど、Latticeにはそんなのない。で、OpenCoresで見つけたやつを試してみる。こちらです。FPUと思われるものはいくつもあるけど、VHDL縛りでこれにしました。
で、ライセンスも一応確認すると、
You can use this code academically, commercially, etc. for free; just acknowledge the author.
って書いてます。何だろうが自由に使っていいらしい。acknowledgeってなんやろって思ったところ、「認める」「感謝する」ということらしい。感謝感謝。Thank you, Al-Eryani, Jidan.
では、fpu_v19.zipをダウンロードしたってことで。なお、このghdlでの試みはwsl内でやります。
こんな感じで、ダウンロードしたファイルを解凍。
そして、
code .
と入力してVSCodeを起動。
こんな感じでMakefileを作る。
VHDLC=/usr/bin/ghdl SRC=fpu_v19/fpupack.vhd fpu_v19/pre_norm_addsub.vhd fpu_v19/addsub_28.vhd fpu_v19/post_norm_addsub.vhd fpu_v19/pre_norm_mul.vhd fpu_v19/mul_24.vhd fpu_v19/serial_mul.vhd fpu_v19/post_norm_mul.vhd fpu_v19/pre_norm_div.vhd fpu_v19/serial_div.vhd fpu_v19/post_norm_div.vhd fpu_v19/pre_norm_sqrt.vhd fpu_v19/sqrt.vhd fpu_v19/post_norm_sqrt.vhd fpu_v19/comppack.vhd fpu_v19/fpu.vhd TBSRC=fpu_v19/test_bench/txt_util.vhd fpu_v19/test_bench/tb_fpu.vhd VCD=fpu.vcd SIMRTL=tb_fpu all : @make comp @make tb @make tb_e @make vcd comp : $(VHDLC) -a --ieee=synopsys -fexplicit $(SRC) tb : $(VHDLC) -a --ieee=synopsys -fexplicit $(TBSRC) tb_e : $(VHDLC) -e --ieee=synopsys -fexplicit $(SIMRTL) vcd : $(VHDLC) -r --ieee=synopsys -fexplicit $(SIMRTL) --vcd=$(VCD)
-fexplicitってのが必要らしいので、追加してある。
これで、
make all
ってすると、
cannot open file "testcases.txt"
とエラーが出る。test_benchに必要なファイル"testcases.txt"がないらしい。これはfpu_v19の下のtest_benchの中で作らんといかんらしい。で、maketest.batを実行すればよさそうに見えるけど、cygwin1.dllがないってことで実行できない。wslのおかげでcygwinをはサヨナラしているので、なんとも、、、で、maketest.batが呼び出しているtimesoftfloatをこちらの環境で作ってしまえばいい。
timesoftfloatのMakefileがあるディレクトリに移動する。
cd fpu_v19/test_bench/SoftFloat/softfloat/bits32/386-Win32-GCC
Makefileをちょいちょいっといじる。
EXE = .exe
は
EXE =
にして、
make
ってすると、
gcc -o timesoftfloat softfloat.o timesoftfloat.o
/usr/bin/ld: timesoftfloat.o:(.bss+0x0): multiple definition of `exceptions'; softfloat.o:(.bss+0x4): first defined here
collect2: error: ld returned 1 exit status
make: *** [Makefile:23: timesoftfloat] Error 1
って出る。exceptionsってのが多重に定義されているらしい。
で、コード内を探っていると、
exceptionsはsoftfloat.hに実態のある形式で構造体として定義されている。
struct {
unsigned int ine : 1;
unsigned int overflow : 1;
unsigned int underflow: 1;
unsigned int invalid: 1;
unsigned int div_zero: 1;
} exceptions;
これを、softfloat.cもtimesoftfloat.cもインクルードしていて、最後にこいつらから作ったobjectをがっちゃんこしているので、同じ名前で別のアドレスに配置されているのが問題になる。
さらに調べると、exceptionを使っているのは、softfloat-specializeってファイルで、このファイルは、softfloat.cがインクルードしているけど、timesoftfloat.cはインクルードしていない。
なので、softfloat.h内のexceptions構造体の定義をコメントアウトする。で、softfloat-specialize内のexceptionsが使われる直前にexceptions構造体をコピペする。でmakeすると、timesoftfloat実行ファイルができる。で、これを実行するmaketestシェルスクリプトを作成する。
#!/bin/sh ./timesoftfloat -nearesteven float32_add > testcases.txt ./timesoftfloat -nearesteven float32_sub >> testcases.txt ./timesoftfloat -nearesteven float32_mul >> testcases.txt ./timesoftfloat -nearesteven float32_div >> testcases.txt #./timesoftfloat -nearesteven float32_sqrt >> testcases.txt #./timesoftfloat -tozero float32_add >> testcases.txt #./timesoftfloat -tozero float32_sub >> testcases.txt #./timesoftfloat -tozero float32_mul >> testcases.txt #./timesoftfloat -tozero float32_div >> testcases.txt #./timesoftfloat -tozero float32_sqrt >> testcases.txt #./timesoftfloat -up float32_add >> testcases.txt #./timesoftfloat -up float32_sub >> testcases.txt #./timesoftfloat -up float32_mul >> testcases.txt #./timesoftfloat -up float32_div >> testcases.txt #./timesoftfloat -up float32_sqrt >> testcases.txt #./timesoftfloat -down float32_add >> testcases.txt #./timesoftfloat -down float32_sub >> testcases.txt #./timesoftfloat -down float32_mul >> testcases.txt #./timesoftfloat -down float32_div >> testcases.txt #./timesoftfloat -down float32_sqrt >> testcases.txt
全部やるとえらいこっちゃなので、一部をコメントアウトする。で、パーミッションも実行属性を追加。
chmod 755 maketest
で、実行。
./maketest
でできたファイルをghdlのビルドフォルダにコピー。
cp testcases.txt ../../../../../..
カレントディレクトリをghdlのビルドフォルダにする。
cd ../../../../../..
で、
make all
すんごい時間がかかる。Ryzen7 5700Uで36分かかったー。
fpu_v19/test_bench/tb_fpu.vhd:251:16:@72000500ns:(assertion failure): Success!!!.......Yahoooooooooooooo
/usr/bin/ghdl-mcode:error: assertion failed
in process .tb_fpu(rtl).verify
from: process work.tb_fpu(rtl).verify at tb_fpu.vhd:255
/usr/bin/ghdl-mcode:error: simulation failed
成功しているはず。
VHDLは
assert false
を実行しないと止められないから、エラーが出て止まるので、紛らわしい。
では、gtkwaveで開いてみる。巨大ファイルなので開くのに4分かかった。
10clockで足し算が完了していて、
0x4EFA0000(=2097152000dec)+0x4EFA0000(=2097152000dec)=0x4F7A0000(=4194304000)
ってなっているので、あっているもよう、、、(てか、あっているかどうかも見たうえで"Success!!!.......Yahoooooooooooooo")って出たんだろうから当然。
ちなみに
足し算 : 10 clocks
引き算 : 10 clocks
掛け算 : 15 clocks
割り算 : 約40 clocks(数えるのがめんどくさい)
でやれるらしい。
いやー浮動小数点演算ってたいへんなんやねー
今年の連休もだらだらすごすぜー!ちなみに、最近は海外でも日本のゴールデンウィークってのは知られているらしい。"Golden Week"ってのが通じる。まぁ日本人が「春節」とか知っているのと同じ感じかな。しかし、こうしてほぼ全国民が同時に比較的長い休日になるのって、西洋にはないような気がする。こうでもしないと(国民の休日にしないと)長期で休みを取りにくい雰囲気だからなのか、、、
コメントをお書きください