web-dev-qa-db-ja.com

Verilogでの除算

私は自分にverilogを教えています。私がフォローしている本は、除算を実行するために「/」演算子または「%」演算子を使用することを導入の章で述べています。後の章では、除算はVerilogには複雑すぎて合成できないため、除算を実行するには長いアルゴリズムが導入されます。

だから私は混乱しています、Verilogは単純な除算を処理できませんか? /演算子は役に立たないのですか?

12
StuckInPhD

それはすべて、あなたが書いているコードのタイプに依存します。

合成するコード、FPGAまたはASICを使用するコードを記述している場合は、除算演算子またはモジュロ演算子を使用したくないでしょう。 RTLに算術演算子を配置すると、シンセサイザはその仕事を実行する回路をインスタンス化します。 +-;の加算器*の乗数。 /と書くと、分周回路が必要になりますが、分周回路は非常に複雑です。多くの場合、複数のクロックサイクルがかかり、ルックアップテーブルを使用する場合があります。 a / bを書くときに、何が欲しいかを推測するために多くの合成ツールに求めています。

(明らかに2の累乗で除算するのは簡単ですが、通常はシフト演算子を使用します)

合成したくないコード、たとえばテストベンチの一部であるコードを記述している場合は、除算を自由に使用できます。

したがって、あなたの質問に答えるために、/演算子は役に立たないわけではありませんが、それをどこでどのように使用しているのかを意識する必要があります。同じことが*にも当てはまりますが、程度は低くなります。乗算器は非常に高価ですが、ほとんどのシンセサイザはそれらを推測できます。

28
Paul S

ハードウェアで考える必要があります。

<= b/cと書くと、合成ツールに「クロックサイクルごとに結果を提供でき、中間のパイプラインレジスタがない除算器が欲しい」と言っています。

あなたがそれを作成するために必要な論理回路を計算する場合、それは特により高いビット数の場合、それは非常に複雑です。通常、FPGAには除算用の特別なハードウェアブロックがないため、汎用ロジックリソースから実装する必要があります。それは大きく(たくさんのたくさんの)と遅い(低いfmax)の両方になる可能性があります。

とにかくそれを実装するシンセサイザーもいます(クイック検索から、Quartusがそうするようです)。他のシンセサイザーは、それが実際に非常に有用であるとは思わないので、気にしません。

定数で除算しておおよその結果が得られる場合は、乗数を使用してトリックを実行できます。割り算したい数値の逆数を取り、2の累乗を掛け、最も近い整数に丸めます。

次に、verilogで、近似的な除算を乗算で実装し(最新のFPGAでは高価ではありません)、シフトを実行します(固定ビット数のシフトはハードウェアで基本的に無料です)。中間結果に十分なビットを許可することを確認してください。

正確な答えが必要な場合、または事前定義された定数ではないもので除算する必要がある場合は、必要な除算器の種類を決定する必要があります。スループットが低い場合は、nクロックサイクルごとに1分周するステートマシンベースのアプローチを使用できます。スループットが高く、デバイス領域に余裕がある場合は、クロックサイクルごとに除算を行うパイプラインアプローチ(ただし、結果が流れるまでに複数のサイクルが必要)の方が適切な場合があります。

多くの場合、ツールベンダーは、この種のもののために事前に作成されたブロック(代替ではメガファンクションと呼びます)を提供します。これらの利点は、ツールベンダーがデバイスに合わせて慎重に最適化していることです。欠点は、ベンダーロックインをもたらす可能性があることです。別のデバイスベンダーに移動する場合は、ブロックをスワップアウトする必要があり、それをスワップするブロックには異なる特性がある可能性があります。

8
Peter green

とても混乱しています。 verilogは単純な除算を処理できませんか? /演算子は役に立たないのですか?

Verilog合成仕様(IEEE 1364.1)は、整数のオペランドを持つすべての算術演算子をサポートする必要があることを実際に示していますが、誰もこの仕様に従っていません。一部の合成ツールは整数除算を実行できますが、組み合わせ除算は通常非常に非効率的であるため、他のものはそれを拒否します(XSTはまだそうです)。マルチサイクルの実装は標準ですが、「/」から合成することはできません。

5
user597225

除算とモジュロは決して「単純」ではありません。可能であればそれらを避けてください。ビットマスクまたはシフト操作を介して。特に可変除数は、ハードウェアでの実装が本当に複雑です。

4
Wormbo

"Verilog the language"は、除算とモジュロを適切に処理します。コンピューターを使用してコードをシミュレートすると、そのすべての機能に完全にアクセスできます。

コードを特定のチップに合成する場合、制限があります。制限は、ツールベンダーが実現可能なものではなく「賢明」であると考えることに基づいている傾向があります。

昔は、2の累乗以外の除算は、多くのスペースを占有し、実行速度が非常に遅いため、シリコンにとっては無意味であると考えられていました。現時点では、一部のシンセサイザーが「定数による除算」回路を作成しています。

将来、シンセサイザがディバイダを作成してはいけない(または将来の可能性のあるアーキテクチャのDSPブロックにあるディバイダを利用しない)理由はないと思います。見られるかどうかはまだ分からないが、乗数の進展が見られる(「2のべき乗のみ」から「1つの入力定数」へ、わずか数年で「完全な実装」へ)。

3
Martin Thompson
  1. 2による除算のみを含む回路:ビットをシフトするだけです:)
  2. 2以外....回路レベルで常にverilogがCまたはC++ではないと考える必要があることを確認してください
  3. /と%が合成可能でないか、それが(新しいバージョンで)なる場合は、独自の除算回路を保持する必要があると考えます。これは、提供するIPが一般的であるためです(おそらく、固定ではなく浮動型にするためです)。
  4. 私はあなたがモリス・マノ・コンピューター・アーキテクチャーの本を通り抜けたに違いない、最後のいくつかの章ではアルゴと一緒に全体の流れが与えられ、それに従って進み、あなた自身のものを作る
  5. 作業が論理検証のみで実際の回路が必要ない場合は、/と%を確認してください。シミュレーションで問題なく動作します
1
Rahul Jain

合成可能なコードが必要な場合は、Divison_IPを使用するか、64/8 = 8 same 64 >> 3 = 8のような一部の除算に右シフト演算子を使用できます。

Verilogでは「/」を使用した除算が可能です。しかし、これは合成可能な演算子ではありません。 「*」を使用した乗算の場合も同様です。これらの操作をverliogで実行する特定のアルゴリズムがあり、コードを合成可能にする必要がある場合に使用されます。すなわち。同等のハードウェアが必要な場合。

除算のアルゴリズムは知りませんが、乗算の場合はブースのアルゴリズムを使用しました。

0
badari259