Article #1127

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

4. 1箇所からしか呼ばれないseqのFSM化

seqをFSMに切り出す第一の理由は再利用で、記事#1035のdrawLivesがそれです。6箇所から呼ばれるseqを1個のFSMにまとめ、コンパイル時間を25%減らしました。記事#1036からは別の狙いで、1箇所からしか呼ばれないseqでも巨大なメインのseqから外せば競合条件の計算量が減るはず、という試みが始まります。記事#1036のdrawTitle1は1度しか呼ばれず本体も薄く、コンパイル時間が1%しか動かなかったので撤回されました。記事#1037のupdateAlienBulletと記事#1038のupdatePlayerBulletは本体が厚く、コンパイル時間がそれぞれ14%と16%、Verilogが11%と19%減って採用され、記事#1039のinitAllも同様に採用されました。つまり効くかどうかは呼び出し回数ではなく本体の厚さで決まる、というところまでが8/3版の時点で分かっていました。

ここではその続きとして、同じ基準で残っていたupdateAliens、updatePlayer、updateSaucerの3つをFSMにし、あわせて逆方向としてupdatePlayerBulletとupdateAlienBulletを展開に戻した場合も測りました。3つを同じ環境で続けてコンパイルしています。

構成 bsc時間 Verilog[KB] メイン状態数 LUT FF
小FSM 7個の現状 0:44 1,965 168 5,812 2,125
1箇所呼びの2個を展開に戻す 0:55 2,597 249 5,770 2,099
1箇所呼びの3個を追加でFSM化 0:45 1,660 94 5,879 2,187

LUTとFFはYosysの概算、時間は2コアの仮想マシンでの値です。展開に戻すとメインFSMの状態数が168から249に増え、コンパイル時間が24%増、Verilogが32%増になりました。逆に3個を追加でFSMにすると状態数は94に減り、時間は同じままVerilogが16%減りました。LUTとFFは逆方向に1%ほど動きます。記事#1037記事#1038で見えていた、本体の厚いseqはメインから切り出す方がbscの負担が軽い、という傾向を逆方向からも確かめた形です。動作はVRAM書き込みの系列がサイクル番号を除いて一致しました。

教科書版の最終形

以上から、教科書版は次の2つの基準で決めました。複数箇所から呼ばれるseqは1個のFSMにして再利用します。メインループから呼ぶ大きなseqは、1箇所からしか呼ばれなくてもFSMにしてメインFSMを小さく保ちます。モジュール境界は、42箇所から呼ばれ自前のレジスタを持つブリッタだけに使います。

seq 呼び出し箇所 扱い 置き場所
copyAreaなど描画プリミティブ6種 42 共有FSM mkBlitter
drawLives 6 共有FSM メイン
waitTicks 4 共有FSM メイン
initAll 2 共有FSM メイン
drawScores 2 共有FSM メイン
updateAliens、updatePlayer、updatePlayerBullet、updateAlienBullet、updateSaucer 各1 メインを小さく保つFSM メイン
updateBonus、checkClear、erasePlayerBulletなど小さなseq 1から5 展開のまま メイン

FSMはmkBlitterの1個とメインの9個で、メインループは各サブシステムのFSMをstartしてdoneを待つだけの短い列になります。メインFSMの状態数は8/3版の194から94になります。


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

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.