· 

FPGAでFPU(1)

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"ってのが通じる。まぁ日本人が「春節」とか知っているのと同じ感じかな。しかし、こうしてほぼ全国民が同時に比較的長い休日になるのって、西洋にはないような気がする。こうでもしないと(国民の休日にしないと)長期で休みを取りにくい雰囲気だからなのか、、、