Posts Issued on October 15, 2025

GameFSMの改良 (13)

posted by sakurai on October 15, 2025 #1035

bugのためかcall順位の上位では出てこなかった関数にdrawLives()がありました。これは自機の残り数を表示するもので、staticには6回呼ばれています。これもFSM化して最適化します。

まず、オリジナルのコードは、

    // 残機表示
   function Stmt drawLives();
      return (seq
         // 残機数字の表示
         copyArea(gun_no*8, 161, 23, 241, 8, 8);
         if (gun_no == 1) seq
            eraseArea(42, 241, 16, 8);
         endseq else if (gun_no > 1) seq
            eraseArea(16*gun_no + 26, 241, 16, 8);
            copyArea(0, 16, 16*gun_no+10, 241, 16, 8);
         endseq // if
      endseq);
   endfunction

ここでgnu_noが自機の数を示します。これを例によってFSM化してメインでは起動し、終了待ちをするだけに変更します。以下が変更後のコードです。

   // 残機表示
   function Stmt drawLives_org();
      return (seq
         // 残機数字の表示
         copyArea(gun_no*8, 161, 23, 241, 8, 8);
         if (gun_no == 1) seq
            eraseArea(42, 241, 16, 8);
         endseq else if (gun_no > 1) seq
            eraseArea(16*gun_no + 26, 241, 16, 8);
            copyArea(0, 16, 16*gun_no+10, 241, 16, 8);
         endseq // if
      endseq);
   endfunction

   // 単一インスタンスのFSMを生成(モジュールスコープ)
   FSM drawLives_fsm <- mkFSM( drawLives_org() );

   // “起動ラッパ”を元の名前に
   function Stmt drawLives();
      return (seq
         `RUN_FSM(drawLives_fsm)
      endseq);
   endfunction

以前作成したマクロは以下のとおりです。

`define RUN_FSM(F)  action F.start(); endaction await(F.done);

以下に結果の表を示します。bsvソース量はほとんど変わらないので表示していません。bscの場合の数が減り、結果の物量は変わらないもののコンパイル時間がかなり減少しています。

自機表示を最適化前後 比較
BSV合成 コンパイル時間 1'54'' 1'25'' ▲25.4%
Verilog合成 ファイルサイズ[KB] 7,509 5,924 ▲21.1%
合成時間 1'00'' 0'51'' ▲15%
Vivado LUT数 5,700 5,551 ▲2.6%
Vivado FF数 1,794 1,790 ▲0.2%


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