Article #1030

既に発行済みのブログであっても適宜修正・追加することがあります。
We may make changes and additions to blogs already published.

GameFSMの改良 (10)

posted by sakurai on September 26, 2025 #1030

前記事でコール順位3位のwait_timerを最適化します。

元のwait_timerは単純に60Hzの外部信号ticに同期して動作する関数です。これをまずwait_timer_orgにリネームします。

   // 時間待ち
   function Stmt wait_timer_org(
      UInt#(12) count
   );
      return (seq
         repeat(pack(extend(count))) seq
         await(tic == 0 || (foa && fbutton));
         await((tic == 1 && sreq == 0) || (foa && fbutton));
         endseq
      endseq);
   endfunction

これに対して、FSM wt_fsmを作成し、さらにそれを起動する汎用マクロを用いたタイマFSM起動関数を元の名前で作成します。

  // ラッパ用:引数をラッチするだけ(Reg は1本)
  Reg#(UInt#(12)) wt_count <- mkReg(0);
  // 本体は org を mkFSM 化(count は Reg 値を読ませる)
  FSM wt_fsm <- mkFSM( wait_timer_org(wt_count) );

  // 同名の薄ラッパ:値ラッチ → 1サイクル待つ → start → done 待ち
  function Stmt wait_timer (UInt#(12) count);
    return (seq
      action wt_count <= count; endaction
      `RUN_FSM(wt_fsm)
    endseq);
  endfunction

このようにすれば、wait_timerを読んでもStmtがほとんど増加せずにFSMに起動をかけ、終了を待つだけになります。本体のStmtとしてはやや小さいものの、前ページのように16回呼ばれているため多少の効果はあるようです。

この関数だけのFSM化効果を調べたら以下のようにverilog量(byte数)で10.6%の削減となったので、そこそこの効果はありました。

wait_timerを最適化前後 比較
BSV合成 コンパイル時間 2:36 2:10 ▲16.7%
Verilog合成 ファイルサイズ[KB] 9,394 8,395 ▲10.6%
合成時間 0:51 0:51 0.0%
Vivado LUT数 5,992 5,901 ▲1.5%
Vivado FF数 1,871 1,812 ▲3.2%


左矢前のブログ 次のブログ右矢

Leave a Comment

Your email address will not be published.

You may use Markdown syntax. If you include an ad such as http://, it will be invalidated by our AI system.

Please enter the numbers as they are shown in the image above.