1

編集:

すべての提案をありがとう。これを元の質問にもっとうまく入れるべきだったので、明確でなくて申し訳ありません。行 prod[0] <= prod[0] + input[0] x weight1[i]; prod[25] までが 200 クロック サイクルにわたって実行されます。ただし、26 の乗算は並行して行われます。一度に多すぎるのでしょうか、それとも 1 クロック サイクルで 1 つの乗算 (32 ビット x 32 ビット) を実行する必要がありますか? つまり、200 x 26 クロック サイクルで 200 x 26 のすべての乗算を行う必要がありますか?

また、全体をパイプライン処理するための 6 つのステージがあります。

  1. 26 の行列乗算を並列で 200 回 (200 クロック サイクル) 繰り返します。

  2. 約 200 要素の LUT で構成されるアクティベーション モジュールが処理を実行し、結果を送信できるように、制御フラグを設定します。ニューロンごとに 25 回繰り返されます (25 クロック サイクル以上)。

  3. フラグをリセットして起動機能を停止します。カウンターとすべてをリセットして、次のパートの準備をします。

  4. 3 つの行列乗算を並列に 25 回 (25 クロック サイクル) 繰り返します。

  5. アクティベーション関数を再度呼び出します。

  6. 6 から得られた 3 つの値の最大値を見つけて、出力がどうあるべきかを判断します (これは分類問題です)。

上記のステージと、1 クロック サイクルあたりの乗算回数 (ステージ 1 で 25、ステージ 2 で 3) は問題ありませんか?

それとも、ステージ 2 を 200x25 クロック サイクルで実行し、ステージ 4 を 10x3 クロック サイクルで実行するようにやり直す必要がありますか?

助けてくれて、アドバイスしてくれたみんな、どうもありがとう。

ファイサル

オリジナル:

人工ニューラル ネットワークのフィードフォワード アルゴリズムのモジュールをコーディングしてシミュレートしました。合成ツールには長い時間がかかります (Synopsys DCS および Xilinx ISE 14.4)...現在 9 時間以上実行されているので、本当に気分が悪いです! ただし、シミュレーション結果は正しいです。

私は新しい設計のアイデアを (メッセージの最後に) 持っていますが、それが私の現在の実装 (以下を参照) よりも効率的かどうか、またはそれよりも悪いかどうかを確認するために、経験豊富な人に実行してもらいたいと考えていました。多くの算術演算がより効率的ですか?

ネットワークの背景:

入力層には 200 の入力があり、

隠れ層には 25 個のニューロンがあり、

出力レイヤーには 3 つの出力がありました。

Verilog コードのアイデア: アルゴリズム全体を実装するモジュールは 1 つしかありません。

  1. 最初のステップは、入力 (200 個) に各ニューロン (25 個のニューロンがある) の重み (200 個) を掛けることです。

prod[0] <= prod[0] + input[0] x weight1[i]; i = 0 to 200-1

.......

prod[25] <= prod[25] + input[25] x weight1[i]; i = 0 to 200-1

そして、200 個の入力のそれぞれについて、上記のことを 200 回繰り返します。25 個のニューロンすべての計算を同時に行っています。

  1. 次に、上記の結果に対して ANN アクティベーション関数が呼び出されます。これは、200 近くの要素を持つ LUT を使用して行われます (case ステートメントを使用しました)。これを行うために、別の activation.v ファイルを作成し、ニューロンごとに 25 回インスタンス化する必要がありました。

  2. 次に、上記の結果に最後の 3 つのニューロンの重みを掛けます。

prod_2[0] <= prod_2[0] + prod[0]*weight2[i]; i = 0 to 25-1;

prod_2[1] <= prod_2[1] + prod[0]*weight2[i]; i = 0 to 25-1;

prod_2[2] <= prod_2[2] + prod[0]*weight2[i]; i = 0 to 25-1; そして、25 個の prod 入力のそれぞれについて、上記を 25 回繰り返します。3 つの出力ニューロンすべてに対して同時に計算を行っています。

  1. 最後のステップは、prod_2[0 から 2] で sigmoid を呼び出すことです。このために、さらに 3 つのアクティベーション モジュールをインスタンス化する必要がありました。

シミュレートされた結果は素晴らしいです。しかし、おそらく恐ろしく非効率です!!!!

それで、これがより良いアイデアかどうか知りたいですか?

Top_Module -> Neuron -> 乗算と活性化

一番上のモジュールはニューロン関数を呼び出し (これには 28 個のニューロンをインスタンス化する必要があります!)、関連する入力と重みをそれに渡します。ニューロン関数は乗算モジュールを呼び出します (最初の部分には 200 個、2 番目の部分には 25 個必要です)。ニューロン関数は次に、上記の 200 個の結果 (パート 2 では 25 個) を追加し、活性化関数を呼び出します。出力は最終的に Top_Module に戻ります。

私の質問:

  1. これは、1 つのモジュールですべてを実行していた以前の実装よりも効率的ですか?

  2. 28 個のニューロンをインスタンス化し、各ニューロンが 200 個の乗算モジュールをインスタンス化することは悪いことですか、それとも良いことですか?

  3. Synopsys Design Compiler が 12 時間もかからないようにコードを効率化する他のアイデアはありますか?

  4. これを行うと、各ニューロンには 200 の入力と、その入力ポートとなる 200 の重みがあります。Verilog モジュールが互いに配列を渡すことができるとは思いませんでした。そうでない場合、配列を渡す代わりに、手動で 400 個のポートすべてを書き出す必要がありますか?

奇妙な質問で申し訳ありませんが、私は合成の概念全体に不慣れで、これらのツールがモジュールをインスタンス化する方法を知りたいですか?

ありがとう、

ファイサル。

4

2 に答える 2

1

これらすべてを並行して実行しようとしているように聞こえますが、これは多くのルーティングと多くの乗数を意味します。

0..200 ループが完了するまでに 200 ティックかかるように、各ニューロンに対して一度に 1 つの input*weight のみを更新するように作業をやり直すことをお勧めします。

于 2013-02-27T10:46:04.987 に答える
1

Synopsys Design Compiler が 12 時間もかからないようにコードを効率化する他のアイデアはありますか?

以前の提案は適切です。現在の設計をすべて見ることはできませんが、モジュール間に十分なパイプライン ステージがあることを確認してください。クリティカル パスがタイミングに対して非常に長い場合、シノプシスは、おそらく不可能なタイミング制約を満たすために乗数を微調整しようとして、長い間すりつぶされます。

また、必要なクロック周波数を下げると、パスの制約が緩和され、合成が容易になる場合があります。

また、200 乗数を保持する場合 (そうすべきだとは言いません)、「合成パーティショニング」を検討すると便利ですが、これを行う方法は、使用している合成ツールによって異なります。基本的に、すべてのモジュールを一度に合成しようとするのではなく、1 つのモジュール/パーティションを合成し、必要な回数だけそのパーティションを複製します。実際には、各乗算ユニットに同じ合成済みネットリストを使用できる場合でも、デザインは 200 個の乗算ユニットすべてを介してそのパスを個別に最適化しようとしている可能性があります。ザイリンクスに関する情報はこちら: http://www.xilinx.com/support/documentation/application_notes/xapp918.pdf

于 2013-02-27T21:26:22.997 に答える