« ANSI C style module declarations | Main | 長門とBrainFuck »

2008.03.13

デジタル回路の速度と高位合成

Advanced FPGA Design: Architecture, Implementation, and Optimizationの一番最初のトピックからすごい。高位合成にもからむ話。

Seedというのは、Throughput、Latency、Timingの3つの要因がある。
Throughput:単位クロックあたりにどれだけのデータが処理できるか
Latency:入力を入れてから結果が出るまでのクロック数
Timing:最大周波数
これに使用リソース(クロック、乗算器、メモリなど)が絡んでくる。

最初の例は、入力の3乗を求める回路。Cで書くとこんな感じ。

XPower = 1;
for(i=0;i<3;i++){
  XPoewr = X * XPower;
}

これをハードに落とすときに、何を重視するかで少なくとも3つの実装があって、それぞれを比べています。
面白そうなので僕もやってみました。そのままだとあんまりなので、16bitのデータの4乗で比較してみます。

回路1:リソース優先


module pow4
  (output reg [15:0] XPower,
   output finished,
   input [15:0] X,
   input clk, start);
  reg [15:0] ncount;
  assign     finished = (ncount == 0);
  always @ (posedge clk)
    if(start)begin
      XPower <= X;
      ncount <= 3;
    end else if(!finished) begin
      ncount <= ncount - 1;
      XPower <= XPower * X;
    end
endmodule

普通にループで回すとこうなります。回路としては遅が、使用リソースが少なく、ncountをロード可能にすることで、4乗以外にも対応できるのが特徴。乗算器の数は少なくなるが、ハンドシェイクやカウンターなどの制御回路が若干増える。

配置配線後のこの回路の性能はこうなります。
Throughput 16/4 = 4bit/CLK
Latency 4clk
Timing 169MHz
9bit multiplier 2

回路2:スループット優先(パイプライン)

module pow4
  ( output reg [15:0] XPower,
    input clk,
    input [15:0] X
    );
  reg [15:0]       XPower1, XPower2, XPower3;
  reg [15:0]       X1, X2, X3;
  always @ (posedge clk) begin
    //pipeline stage1
    X1 <= X;
    XPower1 <= X;
    //pipeline stage2
    X2 <= X1;
    XPower2 <= XPower1 * X1;
    //pipeline stage3
    X3 <= X2;
    XPower3 <= XPower2 * X2;
    //pipeline stage4
    XPower <=XPower3 * X3;
  end
endmodule

普通のパイプライン。レインテンシーとリソースを犠牲にしてスループットを高めたバージョン。これが綺麗に決まるとき、ハードウェア化の意義が出てきます。

Throughput 16bit/CLK
Latency 4clk
Timing 167.39MHz
9bit multiplier 6

回路3:レイテンシー優先


module pow4
  (output reg [15:0] XPower,
   input [15:0] X,
   input clk
   );
  reg [15:0] X1;  
  always @ (posedge clk) begin
    X1 <= X;
    XPower <= X1 * X1 * X1 * X1;
  end
endmodule

X1レジスタは不要なのですが、入れないと速度が測定できなかったので入ってます。1CLKで全演算をしてしまいます。CLK周波数を上げられないので、あまりこういう回路は好きじゃないのですが、通信物のパリティの計算など、どうしても1CLKで計算をし続けないといけないときはこのような回路になります。最近のFPGAは驚くほど早いので、この掛け算でも余裕で50MHz Overで動きます。

Throughput 16bit/CLK
Latency 1clk
Timing 72MHz
9bit multiplier 6

回路の比較

この3つを比較するとこうなります。


回路1 回路2 回路3
Throughput(bit/CLK) 4 16 16
Latency(CLK) 4 4 1
最大周波数(MHz) 169 167 72
9bit乗算器 2 6 6

速度や使用リソースは、Quartus2 Web edition7.2 ターゲットFPGAはEP2C20F484C7で配置配線まで行って求めています。PoorなFPGAの方が差が出やすいのですが、Cycloneは乗算器を持っていないので、Cyclone2で計算しました。

表を見てもらえればわかりますが、こっちを立てるとあっちが立たずになります。AFDには載っていないですが、4乗の場合は2×2というバリエーションもあります。最初の1CLKで2乗を計算し、次のCLKでそれぞれをかけると4乗になります。スループットが16bit/CLK、Latencyが2、乗算器は6個、動作周波数が72MHz~167MHzの間の回路になります。Latencyと動作周波数において、回路2と回路3の中間になります。

高位合成ツールの演算部分というのは、基本的にこれを半自動でやっています。CLKは100MHzで決まりとか、ここで使える乗算器は4つまでと言ったユーザーからの制約を元に、ループの処理を展開したり、一部ループにしたりしています。もちろんこんな単純ではなく、プロセッサのデータパスの設計のように、演算の依存関係を抜き出した上で、レジスタとループとALUをどうするのかを考えてくれます。

この手の話は、Verilogをやっていれば常識の範囲だと思うのですが、なかなか読みやすい形で情報がそろっていません。本屋に売っているVerilogの本には全く載っていないか、載っていても中盤以降であることが多いのです。
AFDは最初のトピックがこれなのがすごい。伊達にAdvancedを名乗っていない。お勧め。

|

« ANSI C style module declarations | Main | 長門とBrainFuck »

Comments

いつも回路を書くときには、回路1、回路2、回路3のどれにしようか?もしくは回路2と回路3の間にしようとか?と思って悩みます。
100MHz動作をさせたいが、2クロックのレイテンシでスループットは16bit/CLKでいけるかどうか?インプリメントしてみるまでわからないというところがあると思います。
皆さん、どうやって見積もりしているんでしょうか? やはり、経験と勘でしょうか?
高位合成ツールで自由にレイテンシとスループットを変えられたら良いのだが。。。と思います。
せめて、なるべくレイテンシやスループットを変えやすい回路構成にしようと思っています。

Posted by: marsee | 2008.03.14 10:10 AM

marseeさん

私の仕事の場合は、全体の設計の過程でCLKの周波数が決まっていることが多いです。
そのCLKと、スループットなり、レイテンシを満たすのであればどれでも良いですが、
無意識に書くときは1演算/1CLKの回路2が多いですね。何が1演算とするかはその回路の
内容次第です。回路3は、設計を放棄しているような気がして嫌なのですが、前後に
FFを追加してRegister Balancingに期待するのも正しいコンピュータの使い方かなと
思っています。

単純に多bitの乗算というだけなら、Coregenなり、MegaWizardなりでレイテンシ
を簡単に変更できるので、積極的に使うようにしています。むしろ、各処理が1CLK
前後しても、全体がうまく動くようにするほうが悩みますね。

Posted by: なつたん | 2008.03.17 09:50 PM

The comments to this entry are closed.

TrackBack


Listed below are links to weblogs that reference デジタル回路の速度と高位合成:

« ANSI C style module declarations | Main | 長門とBrainFuck »