|
19 |
ClaudeによるGameFSMの改善 |
ChatGPT版との差分3点
比較の前は8/3版で、記事#1026から記事#1028でChatGPTが描画関数を1個のサブFSMにまとめてstartとdoneで呼ぶ形にし、そのとき作ったRUN_FSMマクロを使って記事#1035から記事#1039でdrawLives、updateAlienBullet、updatePlayerBullet、initAllを順にFSMにした状態を指します。Claude版はその構造を保ったまま3箇所を書き換え、その上で記事#1035から記事#1039のFSM化を残りのseqに進めたものを4点目としました。以下、各点について書き換え前後のコードと、生成Verilogで確認できる差を示します。数値は、bscのコンパイル時間とVivado 2026.1のxc7a35t向けOOC合成結果を同じPCで測ったもので、LUTとFFにYosysと断ったものは手元の概算です。コードは教科書版に揃えてあります。
1. 文字列テーブル
ChatGPT版はビット連接でBit型の定数を作り、unpackしてVectorに戻していました。連接では先頭の要素が最上位ビット側に置かれ、unpackでは最下位ビット側が要素0になるので、順序を戻すreverseが必要でした。
書き換え前
// str_over: "GAME_OVER"
Bit#(SizeOf#(Vector#(9, Glyph))) str_over_bits = {
pg( 2,186, 89,59, 5, 7), // G
pg( 10,186, 97,59, 5, 7), // A
pg( 18,186,105,59, 5, 7), // M
pg( 26,186,113,59, 5, 7), // E
pg( 34,186,121,59, 5, 7), // _
pg( 42,186,129,59, 5, 7), // O
pg( 50,186,137,59, 5, 7), // V
pg( 58,186,145,59, 5, 7), // E
pg( 66,186,153,59, 5, 7) // R
};
Vector#(9, Glyph) str_over = reverse(unpack(str_over_bits));
書き換え後
// str_over: "GAME_OVER"
Glyph str_over[9] = {
mkGlyph( 2,186, 89,59, 5, 7), // G
mkGlyph( 10,186, 97,59, 5, 7), // A
mkGlyph( 18,186,105,59, 5, 7), // M
mkGlyph( 26,186,113,59, 5, 7), // E
mkGlyph( 34,186,121,59, 5, 7), // _
mkGlyph( 42,186,129,59, 5, 7), // O
mkGlyph( 50,186,137,59, 5, 7), // V
mkGlyph( 58,186,145,59, 5, 7), // E
mkGlyph( 66,186,153,59, 5, 7) // R
};
左辺を配列型で宣言すると{ ... }は配列の初期化子として解釈され、先頭に書いた要素が添字0になります。pgとpack、unpack、reverseは要りません。mkGlyphはChatGPT版にもあった構造体のコンストラクタで、そのまま使っています。
生成Verilogは、行番号に由来する内部識別子を正規化するとdiffが0行でした。LUTとFFは増減なしです。定数の並べ方は静的展開の前にしか存在せず、展開後の回路には残りません。