15 |
GameFSMの改良 (13) |
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% |