FPGAで割り算をやる機会はないのですが、そもそもFPGAで除算ができるのか調べてみました。
VHDLの参考書で確認したところ、分母が2のべき乗であればできるとのこと。
ということで、本当にできるかQuartusを使って調べてみることにしました。
![]() | VHDLによるハードウェア設計入門?言語入力によるロジック回路設計手法を身につけよう (Design wave basic) 新品価格 |

分母を2のべき乗にして、VHDLで試してみる
VHDLで除算の算術演算子は“/”で、剰余は“mod”のようです。
剰余は他にも“rem”というのがあるようですが、“mod”との違いがわかりませんでした。(正の数なのか、負の数なのかで違うらしいですが)
なので、今回は“mod”だけ使います。
“/”と“mod”で、商と余りを求めてみたいと思います。
分母(割る数)は、4で固定します。
分子(割られる数)は、外部ピン(4bit幅)から入力します。
まずはエラー発生
演算子は、“/”と“mod”ということなので、以下のコードを作ってみました。
LIBRARY ieee; USE ieee.std_logic_1164.all; ENTITY divider_hdl IS PORT ( IN_A : IN STD_LOGIC_vector(3 downto 0); OUT_Q : OUT STD_LOGIC_vector(3 downto 0); OUT_M : OUT STD_LOGIC_vector(3 downto 0) ); END divider_hdl; ARCHITECTURE rtl OF divider_hdl IS BEGIN OUT_Q <= IN_A / 4 ; -- 商の計算 OUT_M <= IN_A mod 4 ; -- 余りの計算 END rtl;
しかし、早速のコンパイルエラー発生です。
can’t determine definition of operator “”/”” — found 0 possible definitions
商を求める式でエラーが発生しているので、試しにこの式をコメントアウトして、再度コンパイルしてみました。
can’t determine definition of operator “”mod”” — found 0 possible definitions
“/”も“mod”もダメなようです。
参考書をもう一度確認です。
Integerに変換する必要あり
参考書を確認したところ、”/”と”mod”はIntegerに変換する必要があるそうです。
Integer以外にも、Realでも大丈夫とのことですが、Realも使った経験がないので、ここでは触れません。
VHDLは以下に書き換えました。
LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_unsigned.all; USE ieee.std_logic_arith.all; ENTITY divider_hdl IS PORT ( IN_A : IN STD_LOGIC_vector(3 downto 0); OUT_Q : OUT STD_LOGIC_vector(3 downto 0); OUT_M : OUT STD_LOGIC_vector(3 downto 0) ); END divider_hdl; ARCHITECTURE rtl OF divider_hdl IS signal num_in : integer range 0 to 15; signal num_out_q : integer range 0 to 15; signal num_out_m : integer range 0 to 15; BEGIN num_in <= CONV_INTEGER(IN_A); -- ①Integerに変換 num_out_q <= num_in / 4; -- ②商の計算 num_out_m <= num_in mod 4; -- ③余りの計算 OUT_Q <= CONV_STD_LOGIC_VECTOR(num_out_q,4); -- ④商をSTD_LOGIC_VECTORに変換 OUT_M <= CONV_STD_LOGIC_VECTOR(num_out_m,4); -- ⑤余りをSTD_LOGIC_VECTORに変換 END rtl;
分子(割られる数)は、IN_Aで、外部ピンからの入力を想定しています。
①は、IN_AをIntegerに変換しています。
②と③は、商と余りをIntegerで計算しています。割る数の分母は4で固定です。
④と⑤は、IntegerをSTD_LOGIC_VECTORに戻し、外部ピンに出力しています。
これでコンパイルした結果、エラーが消えました。
コンパイル結果

こちらはコンパイル結果のウインドウです。
Total pinsは12本使用になっていますが、その他のリソースがすべて0%でした。
う~ん、、、なぜでしょう???
シミュレーション結果
分母の割る数は4で固定です。分子の割られる数(IN_A)は、外部ピンから入力します。
シミュレーション時、割られる数のIN_Aは、50ns毎にカウントアップしていくようにしました。
IN_Aは4bit幅なので、0から15までカウントアップし、0に戻ります。
入力データの波形は以下になります。

これで、メニューSimulation -> Run Timing Simulationを実行します。
以下がシミュレーション結果です。

ちょっと小さくなってしまって見づらいと思いますが、商も余りも正しく表示されていそうです。
分母を2のべき乗にした場合のまとめ
コンパイル結果でリソースが0%でしたが、シミュレーションは正しく動いたようです。
分母を2のべき乗にした場合は、割られる数を右にビットシフトさせるだけなので、FPGAのリソースは不要ということなんでしょうか???
今回は、割る数は4なので、割られる数を右に2bitシフトした結果が商で、右に飛び出した2bitが余りになると思うので、コンパイル結果のリソースが0%になったと予想です。
分母を2のべき乗以外にして、VHDLで試してみる
分母が2のべき乗であれば、大丈夫であることがわかりました。
では、2のべき乗以外では、本当にできないのか?を確認してみました。
今回は、分母の割る数を5にしてみました。
以下、VHDLの変更箇所です。
num_out_q <= num_in / 5; num_out_m <= num_in mod 5;
変更後、コンパイルしましたが、エラーはでませんでした。
コンパイル結果

分母が2のべき乗の時は、Total logic elementsが0でしたが、今回は34になりました。
シミュレーション結果
分母が2のべき乗の時と同じ入力条件で、シミュレーションしてみました。
その結果がこちら。

予想に反して、正しく除算をやっていそうです。
分母を2のべき乗以外にした場合のまとめ
分母を2のべき乗以外にすると、論理合成されず、コンパイルエラーになるのかと思っていましたが、予想に反してできました。
Quartusが優秀なのでしょうか?IntelのFPGAが除算に対応しているということなのでしょうか?
残念ながら、詳細はわかりません。。。
RTL Viewerで比較してみる
割る数を4と5にして割り算をやってみましたが、各々の値でFPGA内の回路がどうなっているのかRTL Viewerの機能を使って見てみました。
RTL ViewerはメニューTools -> Netlist Viewers -> RTL Viewerを選択します。
RTL Viewerはこちらの記事でも紹介しているの、ぜひご参照ください。

まず割る数を4にした場合の結果です。

次に割る数を5にした場合の結果です。

この結果をみると、やはり割る数が4の時は、入力データのbit3とbit2を商として出力し、bit1とbit0を余りとして出力しているようです。
なんのロジックも使用されていないので、Total logic elementsが0だったんでしょう。
そして、割る数を5にした時ですが、Div0とMod0というブロックあります。
どうやら、このブロックで商と余りを計算しているようです。
これって、FPGAに内蔵された専用ハードウェアなのでしょうか???
専用のハードウェアだとすると、Total logic elementsは0のままになるはずでしょうか???
Div0とMod0の中身まではちょっとわかりませんでした。
![]() | FPGAチャレンジャー入門編:ALTERA-Cyclone-IV版 キット CD (キットで学ぶ! シリーズ) 新品価格 |

処理時間
最後に、4と5で割った場合に、処理時間がどのくらい変わるのかを比べてみました。
まず、4と5で割って商を求めるシミュレーション結果です。

上の図で、IN_Aの割られる数が11から12になるタイミングを拡大してみました。

割る数が4の時、入力データが変化してから出力データ(商)が確定するまでは約3.6nsでした。
一方で、5の時は、約9.4nsでした。
2のべき乗である4の時は、演算がないので処理時間が短いです。
まとめ
FPGAで割り算はできるのかと疑問でしたが、できることがわかりました。
それと、割る数である分母は、2のべき乗以外でも大丈夫そうです。