ぱたへね

はてなダイアリーはrustの色分けができないのでこっちに来た

s1_coreのクロックを最適化

FPGAプロトタイピングにおけるゲーテッドクロックの扱い

FPGAでプロトタイピングをするときは、クロックをFPGA向けに修正するという作業が入ります。

具体的にはASIC向けPLLを、FPGA内蔵PLLに置き換えます。FPGAが複数にまたがりクロック系統が複雑な場合は、外部に別基板でクロックを生成して各FPGAにクロックを供給することも行います。

次にゲーテッドクロックの削除を行います。ゲーテッドクロックが大きなブロックで設定されていて、クロックを出しっぱなしでも問題の無い場合には、ゲートを削除してクロックは供給しっぱななしにします。

モバイル向けASIC等、超低電力を売りにしているASICではALU単位でクロックにゲートが入っています。この場合は、ゲーテッドクロックをFPGAレジスタのen信号へ置き換えるなどの処理が必要です。シンプリファイ等の合成ツールには、この手の自動変換機能が存在します。

s1_coreのクロックを最適化してみる

sparcのcoreで使われているクロックは、rst_ctrl.vの中で生成されています。

assign gclk_o = (cycle_counter>`GCLK_CYCLES) & sys_clock_i;

シミュレーションでは問題が無くても、実際にFPGAで動かすときは問題があります。動作速度を決めるクロックにゲートが入っていると、タイミング解析時にそのクロックが入っている全てのレジスタにゲート分の遅延が入って来ます。この場合ですと、cycle_counterの全信号がクロックラインにゲートとして入って来ます。

`define TIMER_BITS 16

reg[`TIMER_BITS-1:0] cycle_counter;

cycle_counterはの宣言は16bitなので、16bitの信号、比較用の定数、&が影響してきます。

altclkctrl Megafunction User Guideを参考に、クロックに入る信号をクロック同期した1bitにしましょう。

本来であればこのゲートも取りCLKを出しっぱなしにしたいのですが、それはシミュレーションが動いてからの作業になります。さらにいうと&ではなく、FPGAのプリミティブ(altclkctrl)を使うべきです。今回はクロック修正の影響を見たいので単純にレジスタで&を取ってみます。

  reg clk_en;

  //gated clock enable
  always @(posedge sys_clock_i)
  begin
    if(sys_reset_i==1'b1)
    begin
      clk_en = 0;
    end
    else
    begin
      if(cycle_counter>`GCLK_CYCLES - 1)
      begin
        clk_en <= 1;
      end
    end
  end

  //assign gclk_o = (cycle_counter>`GCLK_CYCLES) & sys_clock_i;
  assign gclk_o = clk_en & sys_clock_i;

rst_ctrl.vの変更点です。clk_enというレジスタを宣言し、cycle_counterが`GCLK_CYCLESを超える1CLK前でHになるようにします。cycle_counter>`GCLK_CYCLES - 1の部分は、cycle_counter==`GCLK_CYCLESでも良いです。

最適化の結果

修正後のrst_ctrl.vでシミュレーションをし、同じ動きになることを確認しました。早速Stratix3で合成してみます。オプションなどの条件はベンチマーク時と全く同じです。

Fitter Status : Successful - Sat Feb 14 15:05:16 2009
Quartus II Version : 8.1 Build 163 10/28/2008 SJ Full Version
Revision Name : s1_top
Top-level Entity Name : s1_top
Family : Stratix III
Device : EP3SL340F1517C3
Timing Models : Final
Logic utilization : 30 %
    Combinational ALUTs : 47,632 / 270,400 ( 18 % )
    Memory ALUTs : 5,278 / 135,200 ( 4 % )
    Dedicated logic registers : 51,291 / 270,400 ( 19 % )
Total registers : 51291
Total pins : 270 / 976 ( 28 % )
Total virtual pins : 0
Total block memory bits : 264,992 / 16,662,528 ( 2 % )
DSP block 18-bit elements : 8 / 576 ( 1 % )
Total PLLs : 0 / 12 ( 0 % )
Total DLLs : 0 / 4 ( 0 % )

合成結果は fmax=42.64MHz となりました。クロック最適化の前がfmax=36.71 MHzでしたので、1割以上も速度が上がっています。クロック以外の回路は同じなのですが、クロックラインを最適化することで、動作速度を上げることができます。