nao-milkの経験ブログ

25年間の半導体エンジニア経験で知り得た内容を記載したブログです。

除算回路を使用しない方法

f:id:nao-milk:20210331130222p:plain

除算回路を使用せずに乗算とビットシフトで演算する方法です。

C言語では、普通に「/」で記述して問題ないですが、半導体設計では除算IPや自作します。

 

5個の8bit値の平均値をとる例で説明します。

尚、前回の記事「浮動小数を使用せず演算」とよく似ていますので、その記事も参考して頂ければと思います。

nao-milk.hatenablog.com

 

平均処理の演算式①

平均処理の演算式を以下に示します。

※式のA~Eは、8bitの値と示します。

f:id:nao-milk:20210331114923p:plain

平均処理の演算式①

 

回路構成①

上記演算式①の回路構成を以下に示します。

f:id:nao-milk:20210331115418p:plain

演算式①のRTL図

A値~E値の合計(最大値は1275)を「5」で割るだけですが、この「割る」という処理を自作した回路に処理するか 又は 除算IPを使用します。

また、除算の結果を得るまでに数クロックかかります。

※クロック周波数、半導体ベンダー 又は IPベンダーにより違う為、確認する必要があります。

 

平均処理の演算式②

除算を使用せず平均処理を行う式を以下に示します。

※「n」はビットシフト量を示します。(固定小数の小数部bit幅を示す)

f:id:nao-milk:20210331120335p:plain

平均処理の演算式②

例えば、

ビットシフト量を18bitと決めてしまうと、係数式「1/5×2^18」となり値は「52428.8」となります。

この「52428.8」の整数値をA値~E値の合計に掛け、その結果を18bitシフトすると除算結果が得られます。

尚、私は「52428.8」の小数点以下四捨五入し、「52429」としています。

 

演算精度を確認

通常計算した場合と、演算式②の方法で演算した場合との誤差を確認します。

 

A値~E値の合計の最大値(=255×5)は「1275」となります。

従って、

割られる値(被除数)は0~1275の範囲となるため、Excelで十分確認できます。

 

以下がExcelで確認した結果となります。

尚、被除数=1~1275の範囲での最大誤差は「0.00097504」となり、小数点以下3桁までは誤差は無いということになります。

f:id:nao-milk:20210331123908p:plain

演算精度確認

 

回路構成②

演算式②の回路構成を以下に示します。

f:id:nao-milk:20210331124818p:plain

演算式②のRTL図

乗算結果は26bitとなり、上位8bitが整数値となるためFFでラッチして平均値を出力します。

※下位18bitは、1/5を掛けた時の小数部となります。

 小数点以下四捨五入したい場合は、TMLT[17]を条件とすれば良いだけとなります。

 

RTL記述例

演算式②のRTL記述(Verilog-HDL)を以下に示します。

f:id:nao-milk:20210401201301p:plain

RTL記述例

21~25行目は加算器4つ使用するため、CKの周波数でタイミングがMetしなかった場合は、FFを用いて加算を分割する必要がある。

乗算(29行目)は固定値と上位8bitを使用することより、タイミングはMetする可能性はあるが、もしMetしなかった場合は、乗算IPを用いてパイプライン化する必要があります。

 

最後に

この方法は1つの例です。

ASIC又はFPGAの規模やDSP数などにより、除算IPを使用した方が良い場合もありますので、こういう方法もあると頭の片隅に置いて頂いて、設計検討して頂ければと思います。