私は自分自身にVerilogを教えています。私がフォローしている本は、導入の章で、除算を実行するために「/」演算子または「%」演算子を使用すると述べています。後の章では、除算はVerilogには複雑すぎて合成できないと言っているので、除算を実行するには長いアルゴリズムが導入されます。
だから私は混乱しています、verilogは単純な除算を処理できませんか?/演算子は役に立たないのですか?
私は自分自身にVerilogを教えています。私がフォローしている本は、導入の章で、除算を実行するために「/」演算子または「%」演算子を使用すると述べています。後の章では、除算はVerilogには複雑すぎて合成できないと言っているので、除算を実行するには長いアルゴリズムが導入されます。
だから私は混乱しています、verilogは単純な除算を処理できませんか?/演算子は役に立たないのですか?
それはすべて、作成しているコードのタイプによって異なります。
合成するつもりのコードを書いている場合、FPGA や ASIC に入れるつもりなら、おそらく除算やモジュロ演算子を使いたくないでしょう。RTL に算術演算子を配置すると、シンセサイザーは回路をインスタンス化してジョブを実行します。+
& -
;の加算器 の乗数*
。と書く/
と分周回路を求められますが、分周回路は非常に複雑なものです。多くの場合、複数のクロック サイクルを要し、ルックアップ テーブルを使用する場合があります。あなたが書くときにあなたが望むものを推測するために多くの合成ツールを求めていますa / b
.
(明らかに、2 の累乗で割るのは簡単ですが、通常はシフト演算子を使用します)
合成したくないコードを書いている場合、たとえばそれがテストベンチの一部である場合、必要なだけ除算を使用できます。
あなたの質問に答えるために、/
演算子は役に立たないわけではありませんが、どこで、なぜそれを使用しているのかを意識しています。同じことが にも当てはまりますが*
、程度は低くなります。乗算器は非常に高価ですが、ほとんどのシンセサイザーはそれらを推測できます。
ハードウェアで考える必要があります。
a <= b/c と書くと、合成ツールに「クロック サイクルごとに結果を提供でき、中間パイプライン レジスタを持たない除算器が必要です」と言っています。
それを作成するために必要な論理回路を考え出すと、特にビット数が多い場合は非常に複雑になります。通常、FPGA には分割用の専用ハードウェア ブロックがないため、汎用ロジック リソースから実装する必要があります。大きい (luts が多い) と遅い (fmax が低い) の両方になる可能性があります。
いずれにせよそれを実装するシンセサイザーもあれば (簡単な検索では quartus が実装するようです)、他のシンセサイザーは、実際にはあまり有用ではないと考えているため、気にしません。
定数で割っていて、おおよその結果を受け入れることができる場合は、乗数を使ってトリックを行うことができます。割りたいものの逆数を取り、2 の累乗を掛けて、最も近い整数に丸めます。
次に、Verilog で、乗算によるおおよその除算 (最新の FPGA ではそれほど高価ではありません) を実装し、その後にシフト (固定ビット数によるシフトは、ハードウェアでは基本的に無料です) を実装できます。中間結果に十分なビットを許可するようにしてください。
正確な答えが必要な場合、または定義済みの定数ではないもので割る必要がある場合は、必要な除算器の種類を決定する必要があります。スループットが低い場合は、n クロック サイクルごとに 1 つの除算を行うステート マシン ベースのアプローチを使用できます。スループットが高く、デバイス領域に余裕がある場合は、クロック サイクルごとに除算を行うパイプライン アプローチ (ただし、結果が流れるには複数のサイクルが必要) がより適切な場合があります。
多くの場合、ツール ベンダーは、この種のものに対して事前に作成されたブロック (アルテラはメガファンクションと呼んでいます) を提供します。これらの利点は、ツール ベンダーがデバイス用に慎重に最適化している可能性が高いことです。欠点は、ベンダー ロックインをもたらす可能性があることです。別のデバイス ベンダーに移行する場合は、ブロックを交換する必要があり、交換するブロックの特性が異なる可能性があります。
だから私は混乱しています。Verilog は単純な除算を処理できませんか? / 演算子は役に立たないのですか?
Verilog 合成仕様 (IEEE 1364.1) では、実際には整数オペランドを持つすべての算術演算子をサポートする必要があると示されていますが、誰もこの仕様に従っていません。一部の合成ツールは整数除算を実行できますが、組み合わせ除算は一般に面積効率が非常に悪いため、それを拒否する合成ツールもあります (XST はまだ実行していると思います)。マルチサイクルの実装は標準ですが、これらは「/」から合成できません。
Division and modulo are never "simple". Avoid them if you can do so, e.g. through bit masks or shift operations. Especially a variable divisor is really complicated to implement in hardware.
「Verilog the language」は、除算とモジュロを適切に処理します。コンピューターを使用してコードをシミュレートする場合、そのすべての機能に完全にアクセスできます。
コードを特定のチップに合成する場合、制限があります。制限は、何が実現可能かというよりも、ツール ベンダーが「合理的」であると考えることに基づく傾向があります。
昔は、2 のべき乗以外の除算はシリコンにとって無意味であると見なされていました。現在、「定数で割る」回路を作成するシンセサイザーもあります。
将来的には、シンセサイザーが分周器を作成しない (または将来のアーキテクチャの DSP ブロックにある分周器を使用する) べきではない理由がわかりません。それが実現するかどうかはまだわかりませんが、乗数の進歩を目の当たりにしています (わずか数年で「2 のべき乗のみ」から「1 つの入力定数」、「完全な実装」へ)。
使用result <= a/b
して完全に動作します。
演算子を使用する場合<=
、答えはすぐに計算されますが、答えは次のクロックの立ち上がりエッジで「結果」レジスタ内に入力されることに注意してください。
次のクロックのポジティブエッジまで待ちたくない場合は、result = a/b.
算術演算回路は、演算を完了するのに時間がかかることを忘れないでください。この間、回路は乱数(ビット)を生成します。
A-10ウォートホグ攻撃機が戦車を攻撃するときのように、多くの弾丸を発射します。これが、分周回路が分周中に動作する方法であり、ランダムなビットを吐き出します。数ナノ秒後、分割が終了し、安定した良好な結果が返されます。
これが、「結果」レジスタを次のクロックサイクルまで待つ理由です。ランダムなゴミの数から保護しようとしています。
除算は最も複雑な操作であるため、計算に遅延が生じます。16ビット除算の場合、結果は約6ナノ秒で計算されます。