9.6 KiB
name, description
| name | description |
|---|---|
| fpga-imx6-flow | Run the fpga-imx6-flow LangGraph workflow at E:\LangGraph_Design\FPGA-imx6-flow — the closed-loop SMOD (FPGA + i.MX6) hardware-in-the-loop design/debug pipeline: power on the board, connect JTAG, program bitstream/flash, restart the imx6 app, analyze (ILA + COM6 serial), judge against design requirements, and iterate by modifying RTL/imx6 code. It drives the graph in-process (no langgraph dev) and hands the 5 interrupts (analyze / meets-requirement / propose / modify-FPGA / modify-imx6) back to this Claude session to execute. ALWAYS use this skill whenever the user wants to run, start, drive, resume, or continue the fpga-imx6-flow workflow / SMOD FPGA+imx6 design loop, or says things like "启动 fpga-imx6-flow", "跑 imx6 设计流程", "run the imx6 FPGA flow", "执行 SMOD 设计任务", "继续 imx6 工作流", "resume the imx6 design loop", even if they don't name the project path. Before driving the workflow this skill first confirms the langgraph conda environment from /langgraph-vivado-install is in place. |
What this skill does
Drives the fpga-imx6-flow graph (24 nodes / 34 flow-edges, 1:1 with
Notes/fpga-imx6-flow.excalidraw). The graph's deterministic hardware/check nodes
(power, JTAG, program, restart) run in-process; its 5 interrupt nodes pause and
hand control to this Claude session, which performs the real work (analysis,
judgment, RTL/app edits) and resumes the same thread. Persistence is a SqliteSaver
file, so start/resume survive across separate process calls.
| Item | Value |
|---|---|
| Project root | E:\LangGraph_Design\FPGA-imx6-flow |
| Conda env | langgraph (C:\Users\bowei\.conda\envs\langgraph) |
| Graph | app.main_graph:build_graph (in-process; no langgraph dev) |
| Driver | C:\Users\bowei\.claude\skills\fpga-imx6-flow\scripts\run_imx6_flow.py |
| Checkpoint | <project>\runs\skill_checkpoint.sqlite (keyed by --thread-id) |
| Design source | Notes/fpga-imx6-flow.excalidraw, plan Notes/Task00.md |
⚠️ 硬件时序铁律(上电 / USB-Blast / 烧写,务必遵守)
每次给 SMOD 上电之前,USB-Blast 必须先断开;上电完成之后再重新连接。 绝不在 USB-Blast 处于连接状态时给板卡上电或断电(保护 JTAG 适配器与板卡)。
标准时序(图拓扑已按此实现,手动操作或写 tools_* / 真机脚本时也必须遵守):
断电(COM8 power_off) → 确认已断电 → 断开USB-Blast(COM4 blast_off) → 确认已断开
→ 上电(COM8 power_on) → 确认已上电 → 连接USB-Blast(COM4 blast_on) → 连接JTAG/烧写/抓ILA
烧写 flash 的完整闭环(固化后必须断电重启从 flash 加载再验证):
断电 → 断开USB-Blast → 上电 → 连接USB-Blast → 用 /fpga_flash 烧写flash
→ 断电 → 断开USB-Blast → 上电 → 连接USB-Blast → 通过ILA验证flash内容正确
- 在 LangGraph 图里:
power_off → check_power_off →(是) blast_off_a → check_blast_off →(是) power_on → check_power →(是) blast_on → check_hw。flash_burn烧写后回到power_off做整机断电重启,再次走完上述上电时序后才analyze(抓ILA验证)。 - 强化确认:
power_on节点在上电前调用_ensure_blast_off_before_power()兜底确认 USB-Blast 已断开;若发现仍连接会强制断开并在history标记rule_violation=True。 - vivado-mcp 工具:
power_on/power_off(COM8 继电器)、USB_Blast_on/USB_Blast_off(COM4)。
Run via the env python directly (not bare
conda run): on this Windows GBK console,conda runre-prints the child's UTF-8 stdout through a GBK codec and crashes on the Chinese interrupt payloads. Use the envpython.exe, orconda run --no-capture-output. The driver also re-configures its stdout to UTF-8.
PY = C:\Users\bowei\.conda\envs\langgraph\python.exe
RUN = C:\Users\bowei\.claude\skills\fpga-imx6-flow\scripts\run_imx6_flow.py
Step 0 — Confirm the environment (REQUIRED before driving)
The workflow runs in the langgraph conda env created by /langgraph-vivado-install.
Verify it before starting, so a missing env surfaces as a clear instruction rather
than a cryptic import error mid-run:
$py = "C:\Users\bowei\.conda\envs\langgraph\python.exe"
if (-not (Test-Path $py)) { Write-Host "[MISSING] langgraph env" } else {
& $py -c "import langgraph; from langgraph.checkpoint.sqlite import SqliteSaver; from langgraph.types import Command; print('[OK] langgraph + checkpoint-sqlite')"
}
- If
[OK]→ proceed to Step 1. - If missing / import fails → tell the user the env isn't ready and to run
/langgraph-vivado-installfirst (it creates thelanggraphenv withlanggraph+langgraph-checkpoint-sqliteand the Vivado link). Do not proceed until it succeeds.
For a real-hardware run (--real), additionally confirm: env_config.json's
VIVADO_BIN_PATH is valid; the vivado-mcp power_on/USB_Blast_on tools are
available; COM4/COM6/COM8 are present ([System.IO.Ports.SerialPort]::GetPortNames()).
Default runs are MOCK (dry-run of the design loop with no hardware), because the
workflow's tools_* real-hardware paths are still TODO — see "Mock vs real" below.
Step 1 — Start the workflow
Ask the user (or infer) the first-pass program mode (bitstream default, or flash)
and any --bit-path/--flash-path. Then start:
& $py $RUN start --project-dir "E:\LangGraph_Design\FPGA-imx6-flow" `
--thread-id "imx6-<short-task-name>" --program-mode bitstream
# add --real only when hardware tools are wired and the board is connected
The driver prints one JSON line and exits:
| Exit | status |
Meaning |
|---|---|---|
| 0 | done |
Workflow finished (符合设计要求 / 迭代到上限) → Step 3 |
| 1 | error |
Read error, diagnose, report to user |
| 2 | interrupt |
An interrupt fired → read interrupt.action → Step 2 |
Step 2 — Handle the interrupt, then resume
On exit 2, the JSON's interrupt.action tells you what the session must do. Perform
it, then resume the same --thread-id with a JSON payload. Repeat until exit 0.
action |
excalidraw node | What you (the session) do | Resume JSON |
|---|---|---|---|
analyze |
通过ila/串口分析 | Grab COM6 serial log + pull ILA waveform (vivado-mcp); summarize | {"analysis_log":"<摘要/路径>"} |
meets_requirement |
符合设计要求? | Judge the analysis against the design requirement | {"meets": true} or {"meets": false} |
propose |
分析原因,提出修改方案 | Diagnose root cause; decide what to change + next program mode | {"reason":"...","need_fpga": true/false,"need_imx6": true/false,"program_mode":"bitstream"或"flash"} |
modify_fpga |
改 RTL→综合→出 bit/flash | Edit RTL, run Vivado synth/impl, produce bit + flash files | {"bit_path":"...","flash_path":"...","program_mode":"flash"} |
modify_imx6 |
VM 改 app→交叉编译 | In the Ubuntu VM (bowei@192.168.223.128) edit app + cross-compile |
{"app_path":"..."} |
Resume command:
& $py $RUN resume --project-dir "E:\LangGraph_Design\FPGA-imx6-flow" `
--thread-id "imx6-<short-task-name>" --resume-json '{"meets": false}'
Notes:
- Always pass the same
--thread-idused atstart— that's how the sqlite checkpoint reattaches to the run (concurrency-safe: different tasks → different thread ids → isolated state). proposefans out to BOTHdecide_fpgaanddecide_imx6; withneed_fpga:falseandneed_imx6:falsethe loop goes straight toround_done→ re-program. Setting either true fires the correspondingmodify_*interrupt next.- After
round_donethe graph re-asks the program-mode decision;program_modeyou set inpropose/modify_fpgachooses bitstream (download bit) vs flash (re-burn + full power/connect re-sequence). This is the big closed loop.
Step 3 — Finish
On exit 0 (status: done), report to the user: iterations completed and that the
design met requirements (or hit the iteration cap). Offer to inspect
<project>\runs\ artifacts or the per-step history.
To abandon a paused run and start clean, delete <project>\runs\skill_checkpoint.sqlite
(or use a fresh --thread-id).
Mock vs real
- MOCK (default) —
FPGA_IMX6_MOCK=1; hardware/check nodes return success immediately. Use this to dry-run the design-loop logic and the 5 interrupts with no board attached. Great for demonstrating/validating the flow. - Real (
--real) — drives actual hardware. Requires the project'sapp/tools_hw.py/tools_vivado.py/tools_imx6.pyreal paths to be implemented (they currently raiseNotImplementedErroras TODO — they will reuse the proven vivado-mcp serial/Vivado logic). Until then,--realfails at the first hardware node; tell the user to wire the tools first (seeNotes/Task00.md§7).
Troubleshooting
| Symptom | Fix |
|---|---|
UnicodeEncodeError: 'gbk' ... |
Don't use bare conda run; use the env python.exe or conda run --no-capture-output. |
import failed ... Run /langgraph-vivado-install |
The langgraph env is missing/incomplete → run /langgraph-vivado-install. |
Exit 1 NotImplementedError ... tools_* |
A --real run hit an unwired hardware tool. Run without --real (mock), or implement tools_*. |
resume seems to start over |
You passed a different --thread-id than start. Use the same one. |
| Need to see the graph visually | Optional: langgraph dev via the project's langgraph.json opens Studio — not required to run. |