10進数の実数と32bitの符号付き固定小数点演算の形式変換処理
研究の都合上,FPGA上で符号付き固定小数点演算を取り扱うことになりました.固定小数点演算を用いた演算器は整数演算と基本的に同じなので特に困ることはありませんが,回路上では全て0と1のbitで処理されるため,固定小数点演算や浮動小数点演算の区別は当然なく,入力値や出力値は01のbitとなります.そして,固定小数点演算ではbit数などのフォーマットが任意のため,入力値を生成する際には自分でbitの形式に変換する必要があり,さらに単純にテストベンチ上での$display等で出力値を表示させることができません.何とかするために調べましたが,浮動小数点演算形式はIEEE754規格に準拠しているため変換ツールなどがいろいろありますが,固定小数点演算形式は任意のため変換ツールがなく,見つけることができませんでした.「無いなら自分で作ればいいか.」ということで,ソースコードの綺麗さ等は何も考えずにとりあえず作成.固定小数点演算のbit数などは浮動小数点演算と比較するために暫定的に32bitと仮定し,ついでにFPGA開発時に使用している複数の言語で実装してみました.全て自分用なので利用する上で不具合等がありますが,メモとして残しておきます.
変換の例
固定小数点演算形式は符号付き32bit(符号1bit,整数20bit,小数11bit)
- 10進数表記(実数)→2進数表記(固定小数点)
-2.74929489937376 ↓ 111111111111111111101.01000000010(ピリオド.は確認用)
- 2進数表記(固定小数点)→10進数表記変換(実数)
111111111111111111101.01000000010 ↓ -2.7490234375(量子化誤差が発生)
実装言語
エクセルVBA(VB.net)
エクセル上でデバッグ用のパラメータ生成や簡易評価に利用.エクセルの関数として利用する形式で,入力値のセルは数値ではなく文字列.エクセルには BIN2DEC や DEC2BIN などの関数が用意されているが,用意されている関数は固定小数点演算や32bit長には対応していない.
- 2進数表記→10進数表記変換
'================================================== ' 固定小数点(2進数,符号付き32bit)を実数(10進数)へ変換 ' 符号部1bit,整数部20bit,小数部11bit(bit幅は調整可能) ' Input : 11111111111111111110101000000010(※文字列) ' Outpot : -2.7490234375 '================================================== Public Function FixedPoint2DEC(dataa As String) As Double Dim IntBit As Integer ' 整数部のbit幅 Dim DecBit As Integer ' 小数部のbit幅 Dim SignBit As Long ' 符号部のbit Dim BitLength As Long ' bit幅 IntBit = 20 DecBit = 11 BitLength = IntBit + DecBit + 1 Dim IntNum As Double '整数部 Dim DicNum As Double '小数部 Dim Result As Double '実数 Dim data(32) As Integer Dim i As Integer Dim temp As String Dim temp_data As String temp_data = dataa Dim Flag As Integer '最上位に検索終了文字を追加(不必要?) temp_data = "\" & temp_data '配列に各bitの値を格納 For i = 1 To BitLength temp = Left(Right(temp_data, i), 1) If temp = "\" Then data(i) = 0 Else data(i) = temp End If Next '値が負(最上位bitが1)の場合,正負逆転+2の補数 If data(BitLength) = 1 Then SignBit = 1 Flag = 1 '2の補数による桁上がりフラグ For i = 1 To BitLength If data(i) = 0 Then data(i) = 1 If Flag = 1 Then data(i) = 0 Flag = 1 End If Else data(i) = 0 If Flag = 1 Then data(i) = 1 Flag = 0 End If End If Next End If ' 整数部の値を計算 For i = (DecBit + 1) To BitLength IntNum = IntNum + data(i) * 2 ^ (i - (DecBit + 1)) Next ' 小数部の値を計算 For i = DecBit To 1 Step -1 DicNum = DicNum + (data(i) * 2 ^ (i - (DecBit + 1))) Next ' 整数部と小数部の結合 Result = IntNum + DicNum ' 値が負の場合は正負を逆転させる If SignBit = 1 Then Result = -Result End If FixedPoint2DEC = Result End Function
- 10進数表記→2進数表記変換
'================================================== ' 実数(10進数)を固定小数点(2進数,符号付き32bit)へ変換 ' 符号部1bit,整数部20bit,小数部11bit(bit幅は調整可能) ' Input : -1.50473253979636 ' Outpot : 111111111111111111110.01111110111(ピリオド.は確認用) '================================================== Function DEC2FixedPoint(dataa As Double) As String Dim IntBit As Integer ' 整数部のbit幅 Dim DecBit As Integer ' 小数部のbit幅 Dim SignBit As Long ' 符号部のbit Dim BitLength As Long ' bit幅 IntBit = 20 DecBit = 11 BitLength = IntBit + DecBit + 1 Dim IntNum As Double Dim DecNum As Double Dim IntOut As String Dim DecOut As String Dim i As Integer Dim DecTemp As Double Dim Flag As Integer ' 整数部を格納 IntNum = Fix(dataa) ' 小数部を格納 DecNum = Abs(dataa - Fix(dataa)) ' 小数部を2進数表示 For i = 1 To DecBit If DecNum = 0 Then ' 終了条件 DecOut = DecOut + "0" Else DecNum = DecNum * 2 '左へ1bitシフト If DecNum >= 1 Then DecOut = DecOut + "1" DecNum = DecNum - 1 Else DecOut = DecOut + "0" End If End If Next i ' 負の場合の処理 If Sgn(dataa) < 0 Then For i = 1 To DecBit DecTemp = DecTemp + CInt(Left(Right(DecOut, i), 1)) * 2 ^ (i - 1) ' 整数として表現 Next DecTemp = ((2 ^ (DecBit + 1)) - 1) - DecTemp ' 正負逆転,2の補数 DecTemp = DecTemp + 1 If DecTemp >= (2 ^ (DecBit + 1)) Then Flag = 1 End If DecOut = "" For i = DecBit - 1 To 0 Step -1 SignBit = DecTemp And (2 ^ i) If SignBit <> 0 Then DecOut = DecOut & "1" Else DecOut = DecOut & "0" End If Next End If ' 参考:http://okwave.jp/qa/q858647.html ' 整数部を2進数表示 If Sgn(dataa) >= 0 Then IntNum = CLng(IntNum) Else ' 正負逆転 IntNum = ((2 ^ (IntBit + 1)) - 1) + CLng(IntNum) ' 小数部の第1桁の桁上がり If Flag = 1 Then IntNum = IntNum + 1 End If End If 'MsgBox "IntNum: " & IntNum For i = 1 To (IntBit + 1) SignBit = IntNum And (2 ^ IntBit) '最上位bitが1か0か判定 If SignBit <> 0 Then IntOut = IntOut & "1" Else IntOut = IntOut & "0" End If IntNum = IntNum * 2 '左へ1bitシフト If IntNum >= ((2 ^ (IntBit + 1)) - 1) Then 'オーバーフロー防止の為、符号無しの&111111..でマスク IntNum = IntNum - ((2 ^ (IntBit + 1)) - 1) End If Next 'MsgBox "IntOut: " & IntOut 'DEC2FixedPoint = IntOut + "." + DecOut DEC2FixedPoint = IntOut + DecOut End Function
Verilog
テストベンチ上で32bitの出力を10進数の実数に変換,デバッグの容易化を狙いとして作成.taskとして実装.
- 2進数表記→10進数表記変換
parameter IntBit = 20; parameter DecBit = 11; task FixedPoint2DEC ( input [31:0]DATA_A ); reg [31:0] DATA; reg SignBit; real IntNum; real DecNum; real Result; begin if ( DATA_A[31]==1'b1 ) begin DATA = ( ~DATA_A + 1'b1 ); SignBit = 1'b1; end else begin DATA = DATA_A; SignBit = 1'b0; end for ( i=DecBit; i<32; i = i+1) begin IntNum = IntNum + DATA[i] * ( 2 ** (i - (DecBit + 1)) ); end for ( i=DecBit-1; i>=0; i = i-1) begin DecNum = DecNum + (DATA[i] * 2 ^ (i - (DecBit + 1))); end Result = IntNum + DecNum; if (SignBit==1'b1) Result = -Result; $display("DATA_A :\t%b\t%f", DATA_A, result); end endtask
- 10進数表記→2進数表記変換
必要ないので未実装.
C言語
FPGA上に構築したNios2に載せる制御用プログラム,そのプログラム上で結果を確認するために利用.
- 2進数表記→10進数表記変換
#define IntNumBit 20 #define DecNumBit 11 double FixedPoint2DEC(unsigned int x) { int temp_data; temp_data = (int)x; double IntNum; double DecNum; double Result; int data[32]; int i; int SignBit; int Flag; IntNum=0; DecNum=0; for(i=0;i<32;i++){ data[i] = temp_data>>i & 1; } if(data[31]==1){ SignBit = 1; Flag = 1; for(i=0;i<32;i++){ if(data[i]==0){ data[i] = 1; if(Flag==1){ data[i] = 0; Flag = 1; } }else{ data[i] = 0; if(Flag==1){ data[i] = 1; Flag = 0; } } } } for(i=DecNumBit;i<32;i++){ IntNum += data[i] * (int)cal_power(2, i-DecNumBit); } for(i=DecNumBit-1;i>=0;i--){ DecNum += (double)data[i] * cal_power(0.5, DecNumBit-i); } Result = IntNum + DecNum; if(SignBit==1) Result *= -1; return Result; }
- 10進数表記→2進数表記変換
必要ないので未実装.
参考リンク
参考書籍
ディジタル数値演算回路の実用設計―四則演算、初等超越関数、浮動小数点演算の作りかた (Design Wave Advanceシリーズ)
- 作者: 鈴木昌治
- 出版社/メーカー: CQ出版
- 発売日: 2006/11
- メディア: 単行本
- 購入: 2人 クリック: 26回
- この商品を含むブログ (10件) を見る