4

画面に720pビデオを出力するために、現在75MHzピクセルクロックの立ち上がりエッジでいくつかの計算が行われています。一部の計算(いくつかのモジュロなど)には時間がかかりすぎるため(20 + ns、75MHzは13.3ns)、タイミングの制約が満たされていません。FPGAは初めてですが、たとえば、75MHzクロックの次のティックまでに計算を完了するために、現在のピクセルクロックよりも速い速度で計算を実行する方法があるかどうか疑問に思っています。ちなみに私はVHDLを使用しています。

4

3 に答える 3

14

75 MHz は、今日の FPGA 規格ではすでにかなり遅いです。

問題はモジュロ演算です。これには実質的に除算が含まれます。そして分裂は遅い。

必要な操作について慎重に検討し、計算を再編成する方法があるかどうかを検討してください。ピクセルをクロックしている場合、処理する 32 ビット整数があるかのようにはなりません。制限された値は扱いやすくなります。

マーティンは 1 つのオプションをほのめかしました: 強度の削減です。1280 ピクセル/ラインがあり、3 つおきに操作する必要がある場合、1280 mod 3 を計算する必要はありません。代わりに 0,1,2,0,... を数えます。

もう 1 つは、8 ビット (または 12 ビット) の数値の modulo-3 が必要な場合は、すべての可能な値をルックアップ テーブルに格納することです。これは十分に高速です。

または、3 で割る代わりに 1/3 (X"5555") を掛けてから、3 を掛けて (これは 1 回の足し算です)、引き算してモジュロを求めることもできます。このパイプラインは非常にうまく機能しますが、X"5555" は 1/3 の近似値にすぎないため、すべての入力に対して正しい出力が得られることをシミュレーションで検証する必要があります。(16 ビット入力の場合、これは大きなシミュレーションではありません!) モジュロ 9 への拡張は簡単です。

編集:

コメントからの 2 つのポイント: 別のオプションは、Spartan のクロック ジェネレーターを使用して X2 クロック (150MHz) を作成することです。これにより、ピクセルあたり 2 サイクルが得られます。適切にパイプライン化されたコードは、大きな問題なく 150 MHz を満たすはずです。

パイプラインしないなんて!

PROCESS(Clk)
BEGIN
    if(rising_edge(Clk)) then
        for i in 0 to 2 loop
            case i is
                when 0 => temp1 <= a*data;
                when 1 => temp2 <= temp1*b;
                when 2 => result <= temp2*c;
                when others => null;
            end case;
        end loop;
    end if;
END PROCESS;

最初に理解することは、ループとケースステートメントが互いに打ち消し合うことです。したがって、これは次のように単純化されます

PROCESS(Clk)
BEGIN
    if rising_edge(Clk) then
        temp1 <= a*data;
        temp2 <= temp1*b;
        result <= temp2*c;
    end if;
END PROCESS;

これはバグです!テストベンチもバグが多く、問題を隠しています。

サイクル 1 では、Data,a,b,c が提示され、temp1 = Data*a が計算されます。
サイクル 2 では、temp1 に正しい値ではなく b の新しい値が乗算されます。
サイクル3でも同じです!

テストベンチは入力を設定して一定のままにしているので、問題をキャッチすることはできません!

PROCESS(Clk)
BEGIN
    if rising_edge(Clk) then
        -- cycle 1
        temp1   <= a*data;
        b_copy  <= b;
        c_copy1 <= c;
        -- cycle 2
        temp2   <= temp1*b_copy;
        c_copy2 <= c_copy1;
        -- cycle 3
        result  <= temp2*c_copy2;
    end if;
END PROCESS;

各サイクルについてコメントしたいと思います。サイクルで使用するすべての用語は、計算またはコピーのいずれかによって、直前のサイクルから取得する必要があります。

少なくともこれは機能しますが、この例では 4 つの入力が独立しているため、2 サイクルの深さとより少ないコピー レジスタに減らすことができます (また、オーバーフローを回避するために必要な対策はないと仮定しています)。そう:

PROCESS(Clk)
BEGIN
    if rising_edge(Clk) then
        -- cycle 1
        temp1   <= a * data;
        temp2   <= b * c;
        -- cycle 2
        result  <= temp1 * temp2;
    end if;
END PROCESS;
于 2013-02-08T16:52:29.113 に答える
12

ここにいくつかのテクニックがあります:

  • パイプライン - ロジックを分割して、複数のクロック サイクルで動作するようにします。
  • マルチサイクル パス - サイクルごとに回答が必要ない場合は、ツールに時間がかかっても問題ないことを伝えることができます。ただし、ツールに間違ったことを伝えないように注意する必要があります。
  • もう一度考えてみてください。たとえば、x mod 3非常に広い範囲で実行する必要があるxか、または継続的に更新されるモジュロ 3 カウンターを使用できますか?
  • より良いツールを使用する - ベンダーのシンセサイザーを使用して同じコードでタイミングを満たさない場合と比較して、高価なシンセサイザーを使用して深いロジック パスでタイミングを満たすことができた例がありました。

より極端なソリューションには、より高速なデバイス、より新しいデバイス、またはより新しくより高速なデバイスのためにシリコンを変更することが含まれます。

于 2013-02-08T13:43:13.240 に答える
2

通常、FPGA の複雑な数学演算はパイプライン処理されます。パイプライン化とは、操作をステージに分割することを意味します。クロック速度に対して時間がかかりすぎる乗数があるとしましょう。乗数を 3 段階に分割します。基本的に、乗算器は 3 つの異なる部分 (独自のクロック入力を持つ) で構成され、その後にチェーンされます。これらの 3 つの部分は 1 つの部分よりも小さいため、遅延が小さくなり、より高速なクロックを使用できます。

これの欠点は「遅延」です。パイプライン化されたシステムは、遅延のある出力を提供します。上記の乗算器の例では、正しい出力を得るために、入力が 3 つのステージすべてを通過するまで待つ必要があります。ただし、これは通常非常に小さく (もちろん設計によって異なります)、無視できます。

これに関する良い (!) 投稿があります: http://vhdlguru.blogspot.com/2011/01/what-is-pipelining-explanation-with.html編集: 代わりに Brian の投稿を参照してください。

また、ベンダーは通常、設計ソフトウェアの IP コアとして最適化されパイプライン処理されたバージョンの数学演算を出荷しています。それらを探してください。

于 2013-02-08T05:28:24.263 に答える