Files
skills-win/fpga_flash/SKILL.md
T
Myfro9andClaude Opus 5 7a11bac29d fix(fpga_flash): 修复写入 Vivado cfgmem 器件表的 w25q128bv 行格式错误
check_flash_csv.py 里 NEW_ROW 是硬编码的 9 字段、从 NAME 开头,而 Vivado
2018.1 的 xicom_cfgmem_part_table.csv 是 14 列、首列为数字 CFGMEM_ID。
Vivado 于是拿 "w25q128bv-spi-x1_x2_x4" 去转 int,抛

    bad lexical cast: source type value could not be interpreted as target

这条错误同时打挂 get_cfgmem_parts 和 refresh_hw_device。后者最具误导性:
它报在硬件刷新阶段,看起来像 probe/.ltx/debug core 的问题,与 CSV 毫无关联,
实际上 refresh_hw_device 内部也读这张表。SMOD 板实测因此完全无法烧写 flash。

改为动态生成:克隆 Vivado 自带的 mt25ql128-spi-x1_x2_x4 行(同为 spi /
x1_x2_x4,COMPATIBLE_DEVICES 含 xc7a200t),只替换 Winbond 相关字段,
字段位置按表头列名定位而非写死下标,换 Vivado 版本 schema 变了也不会写出
畸形行。CFGMEM_ID 取现有最大值 +1。

MEM_DEVICE_ALIAS 指向 n25q128-3.3v-spi-x1_x2_x4 —— Vivado 真正带数据的那个
定义(mt25ql128 也别名到它)。不需要 Winbond 专属数据文件:flash loader
比特流按 FPGA 型号索引(bitfile.zip 里是 spi_xc7a200t_pullnone.bit),
与 flash 型号无关。

其它改动:
- 识别并替换旧版本留下的畸形行(退出码 2),而不是因为 "名字已出现在文件里"
  就误判为已安装直接返回 0
- 改写前自动备份 CSV
- 保留原文件的行尾风格,不整体改写 CRLF/LF

实测(Vivado 2018.1 + SMOD Artix-7 xc7a200t + 真实 W25Q128BV):
- 三条路径均正确:已存在且格式正确→exit 0 且不改文件;全新→exit 2;
  注入 9 字段畸形行→识别并修复→exit 2
- get_cfgmem_parts 可正常返回,属性 MEM_TYPE=spi / MEM_DENSITY=128
- 烧写读回 Mfg ID : ef  Memory Type : 40  Memory Capacity : 18(真实
  Winbond JEDEC ID),Erase / Program-Verify / completed successfully 全过

SKILL.md 排错表补上该症状,并注明报在 refresh_hw_device 上的误导性。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-30 22:19:56 +08:00

159 lines
7.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: fpga_flash
description: |
烧写 Artix-7 系列 FPGA 的外部 Flash(SPI NOR Flash)。适用于 EMV7.1 等 Artix-7 板卡,支持 Micron mt25ql128 和 Winbond w25q128bv 两种 Flash 型号。
当用户提到"烧写 flash"、"flash 编程"、"固化 bit 文件"、"下载到 flash"、"program flash"、"write flash"、"burn flash"、"Vivado flash"、"SPI flash 烧写"时,必须触发此 skill。
---
# FPGA Flash 烧写流程(Artix-7 / EMV7.1)
本 skill 由 Claude **全自动执行**完整的 Flash 烧写流程。除了向用户确认必要信息外,所有操作(文件检查、CSV 修改、Vivado 命令执行、硬件编程)均由 Claude 直接完成,不要求用户手动执行任何命令。
---
## 执行规范
**自动执行原则:**
- 每个需要调用 Vivado 的步骤,Claude 通过 Bash 工具调用 skill `scripts/` 目录下的 Python 脚本
- **禁止**在用户工程目录或系统临时目录(`%TEMP%`、`/tmp`)下创建任何脚本文件
- 所有可执行脚本已预置在 skill 目录的 `scripts/` 子目录中,Claude 只需传入正确的参数调用
**定位 skill 脚本目录:**
Claude 在执行前需先确认脚本的完整路径。使用 Glob 工具查找:
```
C:/Users/<当前用户>/.claude/skills/fpga_flash/scripts/gen_mcs.py
```
或直接使用默认路径:`%USERPROFILE%/.claude/skills/fpga_flash/scripts/`
**scripts/ 目录内容:**
```
scripts/
check_flash_csv.py # 第一步:检查/更新 Vivado Flash 器件表
gen_mcs.py # 第三步:生成 .mcs 文件
program_flash.py # 第四、五步:连接目标板并烧写 Flash
step3_write_mcs.tcl # gen_mcs.py 使用的 Tcl 模板(勿手动修改)
step4_5_program.tcl # program_flash.py 使用的 Tcl 模板(勿手动修改)
```
**调用方式(Bash 工具):**
```bash
python "$USERPROFILE/.claude/skills/fpga_flash/scripts/<script>.py" [参数...]
```
各脚本通过命令行参数接受变量(Vivado 安装目录、工程名、bit 文件路径、mcs 文件路径等),内部调用 Vivado `-mode batch -source <tcl模板> -tclargs <参数>` 完成执行,全程不产生临时文件。
---
## 第一步:检查并修复 Vivado Flash 器件表
**Claude 自动执行:**
调用 `check_flash_csv.py`,检查 `xicom_cfgmem_part_table.csv` 中是否已包含 `w25q128bv-spi-x1_x2_x4`:
```bash
python "$USERPROFILE/.claude/skills/fpga_flash/scripts/check_flash_csv.py"
```
**返回值含义:**
- 退出码 `0`:器件已存在,直接进入第二步
- 退出码 `2`:已成功添加器件行,需提示用户**重启 Vivado** 后才能识别
- 退出码 `1`:CSV 未找到,检查 `~/skills_env.md` 的 `VIVADO_ROOT` 是否指向有效的 Vivado 安装
**Vivado 安装路径不写死在本 skill 里**:三个脚本都通过 `scripts/vivado_env.py`
按 `--vivado-dir` > 环境变量 > `~/skills_env.md` 的 `VIVADO_ROOT`(退化到 `VIVADO_PATH`)
的顺序解析。换机器只改 `~/skills_env.md`,不改 skill。仅在需要临时用另一套 Vivado
时才显式传 `--vivado-dir`。
---
## 第二步:选择 Flash 型号
询问用户板卡上焊接的 Flash 芯片型号,仅支持以下两种:
| 选项 | 厂商 | `--flash-part` 值 |
|------|------|-----------------|
| 1 | Micron | `mt25ql128-spi-x1_x2_x4` |
| 2 | Winbond | `w25q128bv-spi-x1_x2_x4` |
记录用户选择,后续步骤中作为 `--flash-part` 参数传入。如果用户不确定,提示查看板卡丝印或原理图中 Flash 芯片的位号。
---
## 第三步:确认文件路径并自动生成 .mcs
**需向用户确认:**
1. **.bit 文件**的完整路径(通常在工程 `runs/impl_1/` 目录下)
2. **输出 .mcs 文件**的保存路径和文件名(建议与 .bit 文件同目录)
用户确认后,**Claude 自动调用**:
```bash
python "$USERPROFILE/.claude/skills/fpga_flash/scripts/gen_mcs.py" \
--bit-file "E:/Xilinx_design/smod/SMOD_DTMB_CG/RU_golden/RU_golden.runs/impl_1/RU_golden_top.bit" \
--mcs-file "E:/Xilinx_design/smod/SMOD_DTMB_CG/RU_golden/RU_golden.runs/impl_1/RU_golden_smod.mcs"
```
将示例路径替换为用户实际的 .bit 文件路径、.mcs 输出路径(Vivado 路径自动解析,见第一步)。
**验证成功的标志:** 输出中包含 `write_cfgmem completed successfully` 且显示 `0 Errors`。
---
## 第四步 + 第五步:连接目标板、配置存储器并烧写
确认板卡已上电并连接 JTAG 后,**Claude 自动调用**:
```bash
python "$USERPROFILE/.claude/skills/fpga_flash/scripts/program_flash.py" \
--flash-part "w25q128bv-spi-x1_x2_x4" \
--bit-file "E:/Xilinx_design/smod/SMOD_DTMB_CG/RU_golden/RU_golden.runs/impl_1/RU_golden_top.bit" \
--mcs-file "E:/Xilinx_design/smod/SMOD_DTMB_CG/RU_golden/RU_golden.runs/impl_1/RU_golden_smod.mcs" \
--ltx-file "E:/Xilinx_design/smod/SMOD_DTMB_CG/RU_golden/RU_golden.runs/impl_1/RU_golden_top.ltx"
```
**参数说明:**
- `--flash-part`:第二步用户选择的型号
- `--bit-file`:第三步确认的 .bit 路径
- `--mcs-file`:第三步生成的 .mcs 路径
- `--ltx-file`:若设计无 ILA,省略此参数(脚本自动跳过 PROBES.FILE 配置)
此脚本在同一个 Vivado batch 会话中完成:硬件连接 → cfgmem 器件创建 → **载入 flash-loader 比特流(关键步骤)** → 擦除/编程/验证 → 回载用户 bit。
**验证成功的标志(真正写入 flash):** 输出必须包含
`Performing Erase Operation... Erase Operation successful`、
`Program/Verify Operation successful`、`Flash programming completed successfully`,
并能读到非零的 `Mfg ID`(如 Winbond=`ef`、Micron=`20`)。
> ⚠️ 仅有 `End of startup status: HIGH` **不代表写了 flash**——那只是把 bit 载入 FPGA
> 易失配置。若看到 `Mfg ID : 0 / Unable to read device properties`,说明 flash-loader
> 没接管 SPI 总线(本 tcl 已用 `create_hw_bitstream`+`program_hw_devices` 载入
> `spi_<part>_pullnone.bit` 修复此问题)。
ILA core 的 `Dropping logic core` WARNING 是正常现象(载入 loader/golden 镜像时不含 ILA core),不影响烧写结果。
---
## 第六步:上电验证
烧写完成后,提示用户:
1. **断开 JTAG**,给板卡重新上电(或按复位键)
2. 观察 FPGA 是否从 Flash 正常加载(DONE 灯亮起)
3. 如果 DONE 灯不亮,检查:
- BOOT_MODE 跳线是否选择 SPI Flash 启动模式
- MCS 生成时起始地址是否为 `0x0`
- 板卡电源是否满足 Flash 的 VCC 要求(3.3V / 1.8V)
---
## 常见错误排查
| 现象 | 可能原因 | 解决方法 |
|------|----------|----------|
| `check_flash_csv.py` 退出码 1 | `VIVADO_ROOT` 未配置或指错 | 修正 `~/skills_env.md` 的 `VIVADO_ROOT`;临时可传 `--vivado-dir` 覆盖 |
| Vivado 中找不到 w25q128bv | CSV 已修改但 Vivado 未重启 | 提示用户重启 Vivado 后重新执行 |
| `bad lexical cast: source type value could not be interpreted as target`,报在 `get_cfgmem_parts` **或** `refresh_hw_device` 上 | CSV 里的 w25q128bv 行畸形(2026-07-30 之前的版本写的是 9 字段、从 `NAME` 开头,缺了首列数字 `CFGMEM_ID`),Vivado 拿名字当整数解析 | 重跑 `check_flash_csv.py`,它会识别并替换掉畸形行(退出码 2),然后**重启 Vivado**。注意报在 `refresh_hw_device` 上极具误导性 —— 那一步内部也读这张表,看起来像硬件/probe 问题,其实与 `.ltx`、debug core 无关 |
| `No hardware target` 错误 | JTAG 未连接或板卡未上电 | 检查连接后重新执行第四步 |
| DONE 灯不亮 | 启动模式跳线错误 | 检查 MODE 引脚电平,确认为 SPI 启动模式 |
| 烧写后板卡跑旧程序 | Flash 未完全擦除 | 确认 `PROGRAM.ERASE 1` 已设置后重新执行 |
| `PermissionError` 写 CSV | 权限不足 | 提示用户以管理员身份运行 Claude Code |