Appearance
FPGA 環境の解析と展示までの書き込み手順(2026-09-17)
対象: /Volumes/AIWorkSSD/AIWorkSpace/github/aieo-product/fpga-famicom(別 MacBook から複製した checkout)。 NES 純正パッド(#36 / claude/nes-pad-serial*)は対象外(ユーザー判断で中止)。
結論
- レバー GPIO 対応の LCD bitstream は既に手元にある。
build/audio-shared-dc-cdc-integrated/build/nestang_lcd_gowin.fs(2026-09-01 19:32・SHA-256820e2b3f…f536935)は fpga-famicom#17 コメントの LCD ビルドとハッシュが一致する。中身は main 相当+arcade_lever_gpio.v(PMOD0 上段P6 T7 P8 T9= 上下左右、PMOD1T11/P11= Start/Select、Joystick2 も併存)。9/7 の引き継ぎで「main の LCD ビルド」として実機 program され、映像・A/B・Joystick2・Start/Select・音が確認されたのはこのファイル。 - したがって FPGA の再ビルドは不要。Pico 2 ファーム(#15/#19/#22 マージ済み)は GPIO 出力と Joystick2 エミュレーションの両方を出しているので、この bitstream にそのまま繋がる。
- 残る作業は Dock への書き込みだけ。ただし現行方針は volatile SRAM のみで、電源を切ると消える。展示では Flash 書き込みが必要(下記・要判断)。
環境の状態
| 項目 | 状態 | 備考 |
|---|---|---|
Gowin EDA(vendor/gowin) | ✅ あり | gw_sh SHA-256 が Makefile の pin(94eb51ba…)と一致 |
| Docker | ⚠️ 未整備 | Makefile は /Applications/Docker.app の docker と image ID を pin。この Mac は Homebrew docker + colima(停止中)。再ビルドするならイメージ再構築と pin 差し替えが必要 |
| openFPGALoader | ✅ build/programmer-bundle/openFPGALoader v1.1.1(dylib 同梱) | Homebrew 版は未インストール |
HIL wrapper(/usr/local/libexec/fpga-famicom/program_sram、sudoers、usb_reset_ftdi) | ❌ 未インストール | make install-programmer-bundle / install-usb-reset-helper / install-hil-sudoers(sudo) |
| Dock の USB 接続 | ❌ 未接続(9/17 時点) | system_profiler SPUSBDataType に FT2232 が出ない |
| checkout | codex/issue-5-uart-heldout(src-lcd/ddr3_controller_margin.v に未コミット変更)。local main は origin/main より 70 コミット古い | 触らない。作業は build/audio-shared-dc-cdc-integrated worktree(main 19616fa・clean)で行う |
実施記録(2026-09-18)
- Dock を USB 接続 → 同梱
build/programmer-bundle/openFPGALoaderv1.1.1 で sudo なしに JTAG 検出(GW2A-18・idcode 0x81b)。HIL wrapper / sudoers は未インストールのまま使わなかった --write-sramで820e2b3f…を書き込み →--write-flashで内蔵 Flash に書き込み完了(ユーザー指示)。以後は電源投入で自動起動する- 書き込み後の再検出 OK
実施記録(2026-09-18・筐体単体起動 #24)
- Flash 起動の 820e2b3f は ROM を UART で受けるまでグレー画面(UART_RXD=T13 は BL702 直結で PMOD に出ていない)→ 筐体単体では起動しないと判明
- fpga-famicom branch
cabinet/boot-uart-pmod(50d1567): PMOD1J16 = cab_uart_rx/J14 = cab_uart_txを追加(旧 led[0]/led[1])。RX は BL702 と AND で併用 - ビルド環境(この Mac):
colima start default --memory 8 --cpu 4 --mount /Volumes/AIWorkSSD:w(x86_64 VM)→docker build --platform linux/amd64 -t gowin-eda:latest docker/→ wrapper と同じdocker run … gw_sh /work/docker/build_lcd.tclを直接実行(Makefile は Docker.app を絶対要求するため迂回。worktree にはartifacts/を mkdir しておく)。所要 約 18 分 - 生成物:
build/cabinet/nestang_lcd_cabinet_262bf6a7.fs(SHA-256262bf6a7…5fae4276、リリースbitstream-2026-09-18)。STA setup 41 / hold 59 = #17 ビルドと同数 - SRAM で Mac 経路・Pico 経路の両方を確認後、内蔵 Flash に書き込み済み
実施記録(2026-09-18 夕・DDR3 起動ガチャ対策)
- 症状: v2(262bf6a7)を Flash に書き、電源のみのケーブルで起動 → ゲームが出ない。FPGA ログは
DDR3 initialization failed. Retrying...が 20 秒で 155 回、自然回復なし。Flash からの再コンフィグ 3 回で「失敗・成功・失敗」= fpga-famicom#6 の起動ガチャ。DDR3 が死んでいてもGame loading done.は返るため Pico が成功と誤判定していた - 原因箇所: 失敗時の再試行が DDR3 コントローラのリセットのみで、PLL/CLKDIV の位相を引き直していない
- 対策 (FPGA):
pll_kick— 8 連続失敗(1.6 秒)で sys_clk ドメインから PLL を約 4.8ms リセット(commit は branchcabinet/boot-uart-pmod)。v3 =build/cabinet/nestang_lcd_cabinet_509af1b5.fs、リリースbitstream-2026-09-18b。Flash 書き込み済み - 対策 (Pico):
wait_ddr_ready— 失敗ログが 1.5 秒止まるまで送信しない。ack 後にも確認 - 測定: SRAM 書き込み 6 回 + Flash 再コンフィグ 8 回で「失敗し続ける」0 回(うち 8 回は起動直後に 1 回だけ失敗して即回復)。Pico 連動の通し 3 回は全て 1 回目の送信で成功・約 17 秒でタイトル(書画カメラ OCR で確認)
- 未解明: 回復が PLL 引き直しの効果か、v3 の配置配線がたまたまマージンの良いビルドだったのかは切り分けていない(1 回失敗→即回復のブートは PLL 引き直し前に直っている)。STA は setup 57 / hold 42、clk Fmax 32.266MHz で余裕は小さい
- 検証の道具: FPGA の UART ログは BL702(
/dev/cu.usbserial-*1)にもミラーされる。再コンフィグはopenFPGALoader -b tangprimer20k -r
⚠️ 真っ暗・無応答の時は最初に DIP スイッチ 1 番(2026-09-19)
症状: LCD が真っ暗(グレーですらない)、UART は Mac 経由も Pico 経由も無応答、でも JTAG 検出と SRAM 書き込みは DONE で成功する。どの bitstream でも同じ。 原因: Dock 下辺の赤い 5 連 DIP スイッチの 1 番が OFF。このデザインの sys_resetn(FPGA ピン T2)に繋がっており、OFF だとリセットが掛かったまま全クロックが止まる(CLKDIV.RESETN = sys_resetn & nes_lock)。配線や移動で触れて動きやすい。 対処: 1 番を ON。筐体に組む時は ON 側でテープ留めするか、ホットボンドで固定する。
切り分けに使った手順: ① openFPGALoader --detect(JTAG 生存)② SRAM に既知の良品 bitstream を書いて Mac から ROM 送信 → Game loading done. が返るか ③ Pico の GP0/GP1 を入力にして J16/J14 の線のレベルを読む(両方 HIGH が正常)。
書き込み手順(SRAM・公式経路)
Dock を USB で Mac に繋ぎ、Joystick2 実機と Pico は外した状態で:
sh
cd /Volumes/AIWorkSSD/AIWorkSpace/github/aieo-product/fpga-famicom/build/audio-shared-dc-cdc-integrated
make install-programmer-bundle # sudo。/usr/local/libexec/fpga-famicom/ に wrapper を置く
make install-usb-reset-helper # sudo
make install-hil-sudoers # sudo。program_sram だけを NOPASSWD にする
make hil-doctor # 読み取り専用の事前確認
make hil-lcd-program # build/nestang_lcd_gowin.fs(820e2b3f…)を volatile SRAM へprogram 後、電源を切らずに 黒 GND → 5V0 → SDA/T8 → SCL/P9 の順で Pico を接続(README の Joystick2 手順と同じ)。GPIO 側(P6 T7 P8 T9 / T11 / R8 T6)は open-drain なので順序不問。
Flash 書き込み(展示用・要判断)
SRAM は電源断で消えるため、展示中に電源を入れ直すたびに Mac から program し直すことになる。回避策は 内蔵 SPI Flash に書くこと。fpga-famicom の wrapper は安全のため --write-sram 固定で Flash を扱わない(README「Flash は使用しない」)ので、やるならプロジェクト方針の外で手動:
sh
cd /Volumes/AIWorkSSD/AIWorkSpace/github/aieo-product/fpga-famicom
sudo DYLD_LIBRARY_PATH=build/programmer-bundle \
build/programmer-bundle/openFPGALoader -b tangprimer20k --write-flash \
build/audio-shared-dc-cdc-integrated/build/nestang_lcd_gowin.fs- 書く前に SRAM で動作確認を済ませる(同じ .fs)
- Flash 書き込み後は電源投入で自動起動。SRAM program で上書きすれば一時的に別イメージを試せ、電源を入れ直せば Flash に戻る
- 元に戻したい時は同じコマンドで別の .fs を書く。NESTang v0.4 の
vendor/nestang-0.4-dock.fsも手元にある
再ビルドが必要になった場合(今回は不要)
- colima を起動し、
docker/Dockerfileからgowin-eda:latestを build(Apple Silicon は amd64 エミュレーション) tools/build_gowin.sh --profile lcdをDOCKER_BIN=/opt/homebrew/bin/docker GOWIN_IMAGE_ID=<新 ID>で直接呼ぶ(Makefile のoverride DOCKER_BINを迂回)- 生成物の SHA を記録し、HIL の strict gate(unconstrained 0)を確認
参照
- fpga-famicom#17 コメント(2026-09-01): ピン割当・ビルド SHA
docs/HANDOFF-2026-09-07.md(origin/main): 9/7 時点の実機状態、電源断で SRAM が消える注意docs/lcd-validation-2026-08-28.md: LCD 版の実機 PASS 手順