2012年7月5日木曜日

固定小数点演算信号処理の極意シリーズ (その6) 加算で増えるbit幅

前回はverilogの記述方法について簡単に説明しました.今回は、加算したらbit幅が増えることについて説明します.

4bit+4bitの加算をしてみます.
   3+8 = 11        0011+ 1000 = 1011
この例では4bit+4bitは4bitに収まっていて、bit幅は増えません.
けれど、この例ではどうでしょうか?
  12+13 = 25      1100 + 1101 = 11001
あら~答えが5bitになっちゃった.でもまぁ和が25なんだったら5bitに増えるのはやむを得まい.一般的にどう対処したらいいんだろう?

↑これが今回解決したい問題点です.つまり、
     4bit+1bitは何bitになるのか?  4bit+2bit+2bitは何bitになるのか?
こういうことを法則として理解できてないと、固定小数点演算回路を設計することはできません.答えが18bitになるはずなのに、16bitで設計しちゃったらオーバーフローして計算結果がバグバグになってしまいますからね.

いきなり難しい実例ですが、下記の加算回路の各部分のbit幅を求めてみましょう.
この回路は、左側から(1.7.6)の符号付き固定小数点信号が入力されます.(1.7.6)の意味は、1が符号、7が整数部bit数、6が小数部bit数の意味です.------こちらのページの下の方で説明しました-------    それに加算されるのは(1.7.7)が3つと(1.7.6)が1つという複雑な加算構造になってます.
では、A~Dまで順に追ってゆきます.

A:  初段なので簡単です. (1.7.6) + (1.7.7)  = (1.8.7) になります.
出力法則は ①小数部は大なる桁数で統一する  ②整数部は大なる桁が1桁増える  ③符号は両方が符号付きでも1桁のまま  ③符号は片方が符号付きなら1桁充てる  ③符号は両方とも符号なしなら0桁
つまりこの例では、
①小数部は片方が6bit、片方が7bitですから、出力は7bitです.
②整数部は両方とも7bitですから、出力は8bitになります.
③符号は1bitのまま.
すなわち (1.8.7)になります.出力Aを(1.8.7)という桁サイズに受けておけば、どんな数値が入力されても数値的にオーバーフローしなくて済むというわけです.

そしてverilog codeはこうなります.A1[13]とかA2[14]はなんだろ?と思うでしょうね.それは次回解説しますので、今回はverilog codeはこれ以上はお見せしません.
wire [13:0] A1;  // (1.7.6)
wire [14:0] A2;  // (1.7.7)
wire [15:0] A = {A1[13],A1[13],A1} + {A2[14],A2}; // (1.8.7)

B: 2段目以降は複雑化します.そもそも式を書くのがかったるい.なぜなら、AとBで登場する項を全部書かなくちゃいけないからです.すなわちこうなります.  (1.7.6) + (1.7.7) + (1.7.7) とこう書きます.この式をどうやって料理するか? 同じ桁数の項同士を最初に足します. 2つある(1.7.7)を足すと(1.8.7)になる法則はAで示しました.そのおかげで、(1.7.6) + (1.8.7) と2項に簡素化できました.2項を足す法則はAで示しました.結果はBが(1.9.7)になります.

C: もっとめんどくさくなります.AとBとCで登場する項を全て書きますと、 (1.7.6) + (1.7.7) + (1.7.7) + (1.7.7) になります.末尾の同じ桁数の項同士を最初に足しますと、 (1.7.6) + (1.7.7) + (1.8.7) になります.さらに、左側の2項を足しますと、(1.8.7) + (1.8.7) になります.最後にCが (1.9.7) を得ます.おもしろいことになりました.BもCも(1.9.7)で同じです.これはBは余裕があったからです.

D: 究極的にかったるいです.ABCDで登場する項を全て書きますと、 (1.7.6) + (1.7.7) + (1.7.7) + (1.7.7) + (1.7.6) になります.左右の(1.7.6)を片づけますと(1.8.6)ですから、(1.8.6) + (1.7.7) + (1.7.7) + (1.7.7) になります.末尾の(1.7.7)を片付けますと(1.8.7)ですから、(1.8.6) + (1.7.7) + (1.8.7)になります.(1.8.6)と(1.8.7)を片付けると(1.9.7)ですから、(1.9.7) + (1.7.7)になります.最後にDが(1.10.7)を得ます.

⑤の法則性はかっちりと書きにくいのですが、上手いこと考えて2項ずつ消してください.

このように、入力では(1.7.6)の14bitだったのが、出力では(1.10.7)の18bitに膨らんだという結果を得ました.逆に言うと、上図の構成でオーバーフローを生じさせない安全な回路を設計するには、出力18bitが必要ですよということです

なお、ここでは加算回路を例にしましたけれど、減算回路でも同じです.マイナス符号の加算と思えば同じですから.

読者の中には、加算結果がどんどん増えて行くのを困ったなぁと考えている方もいらっしゃると思います.たとえば、この加算回路の出力をどうしても16bitのメモリに格納しなくちゃいけないときなどです.そういうときは、たとえ値がサチッてもいいから、16bitに丸めたいわけです.

丸めるやり方を次回で説明します.次回はverilog codeが出まくりです.

つぎへ            前へ

人気ブログランキングへ

0 件のコメント:

コメントを投稿