Skip to content

FPGA 環境の解析と展示までの書き込み手順(2026-09-17) ​

対象: /Volumes/AIWorkSSD/AIWorkSpace/github/aieo-product/fpga-famicom(別 MacBook から複製した checkout)。 NES 純正パッド(#36 / claude/nes-pad-serial*)は対象外(ユーザー判断で中止)。

結論 ​

  1. レバー GPIO 対応の LCD bitstream は既に手元にある。build/audio-shared-dc-cdc-integrated/build/nestang_lcd_gowin.fs(2026-09-01 19:32・SHA-256 820e2b3f…f536935)は fpga-famicom#17 コメントの LCD ビルドとハッシュが一致する。中身は main 相当+arcade_lever_gpio.v(PMOD0 上段 P6 T7 P8 T9 = 上下左右、PMOD1 T11/P11 = Start/Select、Joystick2 も併存)。9/7 の引き継ぎで「main の LCD ビルド」として実機 program され、映像・A/B・Joystick2・Start/Select・音が確認されたのはこのファイル。
  2. したがって FPGA の再ビルドは不要。Pico 2 ファーム(#15/#19/#22 マージ済み)は GPIO 出力と Joystick2 エミュレーションの両方を出しているので、この bitstream にそのまま繋がる。
  3. 残る作業は 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 が出ない
checkoutcodex/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/openFPGALoader v1.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): PMOD1 J16 = 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-256 262bf6a7…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 は branch cabinet/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 も手元にある

再ビルドが必要になった場合(今回は不要) ​

  1. colima を起動し、docker/Dockerfile から gowin-eda:latest を build(Apple Silicon は amd64 エミュレーション)
  2. tools/build_gowin.sh --profile lcd を DOCKER_BIN=/opt/homebrew/bin/docker GOWIN_IMAGE_ID=<新 ID> で直接呼ぶ(Makefile の override DOCKER_BIN を迂回)
  3. 生成物の 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 手順