点数表示にバグが…

●プロンプト

FPGAで動く1キーゲームを作る
# Application
なつかしの1キーゲームを作ってください.画面はLCDに表示します.
1ドット幅の線が自動的に伸びていきます.ボタンを押している間は線の伸びる方向が切り替わります.
線がゲームフィールドの右端にあたると,線の進む方向(左右)が反転します.
線がゲームフィールドの上端,下端に達するか,線と線が重なるとGame Overです.
## Specification
・画面は横向き(Landscape)に使う
・ゲームフィールドは320×200
・画面下側の320x40領域は,情報表示(Scoreなど)領域にする
・画面は左右方向がX軸(右向きが+),上下方向をY軸(下向きが+)とする
・ユーザ入力装置として,ボタンAを使う
## 動作
1.座標(0,0)を起点に,右下に直線が伸びていく(1ドット線が伸びるごとにScore に1を足す)
2.以降は,次の条件でGame Overとする(Game Overになったら,2秒待ち,その後ボタンを押すと,初めからプレイ)
 ・線がゲームフィールの上端(Y:0)に触れる
 ・線がゲームフィールの下端(Y:200)に触れる
 ・線がすでに描画した線に触れる
3.ボタンAを押している間だけ,直線が伸びる方向を反転する(上向きにする)
4.ゲームフィールドの右端(320)まで線が行くと,線が伸びる方向(符号)を反転する
5.ゲームフィールドの左端(0)まで線が行くと,線が伸びる方向(符号)を反転する
# HDL
SystemVerilog
# IDE
Quartus Primer Lite
# Hardware
## System Clock
50MHz
## FPGA
max10(10M08SCE144C8G)
## Board
### Core Board
https://fpga.tokyo/wp-content/uploads/2024/07/CQ-MAX10-A_%E5%9B%9E%E8%B7%AF%E5%9B%B3_R0.pdf
### Base Board
PCB_CQmax10
https://github.com/Lathe-Mariel/PCB_CQmax10
## LCD Module
PMOD-TFTLCD v1.1
### Resolution
320x240
### Driver IC
ILI9341
# 物理制約
信号 | 役割り | FPGA Pin No.
clk | system clock | 85
btn_rst | Reset_n | 17
Button | User Button | 62
lcd_cs | lcd chip select | 81
lcd_mosi | lcd mosi | 78
lcd_sck | lcd spi clock | 75
lcd_dc | lcd dc | 77
広げる

●Claude Code応答

一式作りました。構成は以下の通りです。

モジュール構成

reset_sync.sv — btn_rst(17)の非同期解除を同期化
debounce.sv — Button(62)のチャタリング除去
spi_byte_master.sv — 4線write-only SPI(mode0, MSBファースト)
lcd_ili9341_ctrl.sv — ILI9341初期化+FILL_RECT一本化コマンド(1x1指定でドット描画も兼用)
font5x7_pkg.sv — スコア表示用5x7フォント(0-9)
game_core.sv — ゲーム本体(座標・方向・衝突判定・スコア・ステートマシン)
line_game_top.sv — トップ、ピン結線
line_game_pins.tcl — Quartus用ピン/IO規格割当

ゲームロジックの要点

(0,0)起点、既定は右下45度に1ステップずつ進む
ボタン押下中はY方向のみ反転(上向き)、X方向はフィールド端(0,320)で自動反転
衝突判定は320×200bitの1bit配列(M9Kへの推論を想定、(* ramstyle="M9K" *)のフォールバック案もREADME記載)
Y端(0,200)到達 or 自己交差でGame Over→2秒待機→ボタン離す→押すで再スタート
スコアはdouble-dabbleで2進→BCD変換し、下側40pxの情報領域に毎ステップ再描画
広げる

●デバッグ1

生成されたファイル群をQuartus Prime Liteで合成しましたが,エラーが発生しました.Claude Codeにエラーメッセージを伝えます.

Error (10170): Verilog HDL syntax error at game_core.sv(327) near text: “[“; expecting “;”.

Fixed. The error was in game_core.sv line 327: Quartus’s SystemVerilog parser doesn’t accept a bit-select applied directly to a function call’s return value, i.e. digit_row(...)[4-cell_col]. I split it into two steps — assign the function result to a local glyph_row variable, then index that:

●デバッグ2

修正されたファイルを使って,再度合成します.再びエラーが発生しました.今一度Claude Codeに問い合わせます.

合成できない記述があるようです.FPGAで動作させるので,合成できる記述に変更してください

非合成的な記述の心当たりを一通り洗い出して直しました。主な変更点:

1. lcd_ili9341_ctrl.svinitialブロックを削除
初期化シーケンスROMをinitial begin ... endで埋めていました。宣言時に値を与える配列リテラル(localparam ... = '{...})方式に変更し、initialを完全に排除しました。

2. game_core.sv / spi_byte_master.sv — パラメータ幅の'(...)キャストを排除
ADDR_W'(MEM_DEPTH - 1)DW'(HALF_PERIOD - 1)のような「パラメータ幅を使ったサイズ付きキャスト」構文をやめ、localparamで定数として定義してから比較する形に変更しました。

3. game_core.svcase項目内のローカル変数宣言をモジュール直下に移動
begin...endブロックの中でlogic [...] 変数;と宣言していた箇所(BCD変換用の一時変数、フォント行の一時変数)を、他の信号と同じようにモジュール先頭でまとめて宣言する形に統一しました。

4. ついでに見つけたロジックバグも修正
next_x/next_yはボタン状態から毎サイクル組合せ的に再計算される値だったため、1ステップの途中(描画待ち〜コミットまでの複数サイクル)でボタンが変化すると、LCDに描いたドットと衝突判定・座標更新に使う値がズレる可能性がありました。

再度Analysis & Synthesisを回してみてください。もし別のエラーが出た場合は、お手数ですがそのエラーメッセージ(ファイル名・行番号・テキスト)を貼っていただけると、ピンポイントで直せます。

3つのファイルが修正されました.再度合成すると,ゲームが動きました.

●参考文献

(1)GitHubリポジトリ

コメントを残す