Files
skills-win/smod_atsc_dev/SKILL.md
T
2026-07-20 18:26:14 +08:00

152 lines
9.2 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: smod_atsc_dev
description: >
在 SMOD 硬件平台(Artix-7 xc7a200t + i.MX6 + ADRV9009)上开发、调试、固化 ATSC 激励器:
改 RTL 并用 vivado-mcp 综合实现、在 Ubuntu VM 上交叉编译 imx6 的 atsc_app 并部署、
用 ILA/串口/频谱做闭环验证。(生成 quickboot .mcs 和远程升级 FPGA 转交 fpga_update skill。)
只要用户提到 SMOD、my_exciter、RU_golden、smod_top、atsc_app、ATSC 激励器、8VSB 调制、
ADRV9009/ORx/DPD/TxAGC、tuner(Sony CXD2878)、TSoIP、quickboot、远程升级 mcs、192.168.1.143、
或在 E:\Xilinx_design\smod\SMOD_ATSC 下做任何 FPGA / imx6 改动,就必须使用这个 skill —— 即便
他们没点名 "skill",也没说 "SMOD",只是说 "把新 bit 升上去"、"改一下激励器的 RTL"、
"imx6 app 编译部署一下"、"抓个 ILA 看看"、"重新出个 mcs"。这个 skill 给出平台事实、
两条烧写路径的选择、上电时序铁律,并把闭环调试转交给 fpga-imx6-flow。
---
# SMOD ATSC 激励器开发
SMOD 是一块 **Artix-7 (xc7a200tfbg676-2) + i.MX6 + ADRV9009** 的 ATSC 激励器板。
FPGA 做 8VSB 调制 / DPD / AGC / TS 前处理,imx6 跑 `atsc_app`(配置 ADRV9009、tuner、
网页、SNMP),两者通过一个 I2C/寄存器桥通信。
这个 skill 是**总入口**:它告诉你平台的硬事实、该走哪条烧写路径、以及什么时候把活
交给别的 skill。具体细节在 `references/`,可直接运行的脚本在 `scripts/`。
## 平台事实速查
| 项 | 值 |
|---|---|
| 激励器 Vivado 工程 | `E:\Xilinx_design\smod\SMOD_ATSC\my_exciter\my_exciter.xpr`(top = `smod_top`,也是 **git 仓库根**) |
| 打底 golden 工程 | `E:\Xilinx_design\smod\SMOD_ATSC\RU_golden\RU_golden.xpr`(top = `RU_golden_top`) |
| FPGA / Flash | `xc7a200tfbg676-2` / Winbond **w25q128bv**(128 Mbit = 16 MB,SPIx1) |
| Vivado | `D:\Xilinx\Vivado\2018.1`(`bin\vivado.bat`) |
| imx6 源码 | `my_exciter\imx6\src\atsc_app`(Makefile 在该目录根) |
| imx6 设备 | `192.168.1.143`,用户 `root`,密码见 `~\skills_env.md` 的 `SMOD_SSH_PASS`(网页 + SSH;Windows 主机 `192.168.1.125` 同网段) |
| 交叉编译 VM | `bowei@192.168.223.128`,密码见 `~\skills_env.md` 的 `CROSS_VM_PASS`,构建目录 `~/atsc_head_build` |
| 工具链 | `/opt/fsl-imx-x11/4.1.15-2.0.0/environment-setup-cortexa7hf-neon-poky-linux-gnueabi` |
| app 部署路径 | `/aw/anywave/app/imx_atsc_app`(先写 `imx_atsc_app_head`,再 `cp -a` 覆盖 active) |
| app 日志 | `/var/module_log/imx_atsc_app.log` |
| 串口 | COM 号**逐机而异,两处配置都在 `~` 下、都不入库**:两个继电器(电源 / USB-Blast)看 `~/vivado_mcp_usb.conf`(缺了就跑 vivado-mcp 的 `detect_serial_relays` 自动探测生成);imx6 控制台看 `~/fpga_imx6_flow.json` 的 `ports.imx6`。**任何地方都不要写死 COM 号。** |
| 原理图 | `my_exciter\Notes\SMOD_V1.0_SCH251010.PDF` |
| 构建产物约定 | `my_exciter\bitstream\<tag>.{bit,ltx,mcs,prm}`,一次迭代一个 tag(`smod_p1`、`smod_dpd`…) |
## ⚠️ 硬件铁律:上电时序
**给 SMOD 上电/断电之前,USB-Blast 必须先断开。** 绝不在 USB-Blast 连接状态下切换板卡电源
——这会打坏 JTAG 适配器和板卡。
```
断电(power_off) → 断开 USB-Blast(USB_Blast_off) → 上电(power_on) → 连接 USB-Blast(USB_Blast_on) → JTAG/ILA
```
用 vivado-mcp 的 `power_on` / `power_off` / `USB_Blast_on` / `USB_Blast_off` 工具执行。
上电后要**等 imx6 串口控制台打印 `sys init over` 再连 JTAG**,否则 TX 链路会挂掉。
## 两条烧写路径 —— 先选对,再动手
这是本平台最容易搞错的地方。板上 flash 是 **quickboot 双镜像**布局:golden 镜像在
`0x000000..0x3FFFFF`,update 镜像在 `0x400000..0xBFFFFF`,切换字 `0xAA995566` 在 `0x000FFC`。
| | **A. JTAG 直烧** | **B. 网络远程升级**(PR07 主线) |
|---|---|---|
| 何时用 | 板子是砖 / 首次装机 / 要换 golden | 日常迭代,板子已有 golden 且网络能通 |
| 烧什么 | `RU_golden\bitstream\golden_design_initial.mcs` | `my_exciter\bitstream\<tag>_update.mcs` |
| 怎么做 | `/fpga_flash` skill(flash 型号 `w25q128bv`) | **`/fpga_update` skill** |
| 需要 | USB-Blast + 上电时序 | 只要 `192.168.1.143` 能访问 |
| 风险 | 高(要动电源和 JTAG) | 低(写坏了 golden 会兜底) |
**调试期**还有第三种:`program_device` 直接把 `.bit` 下到 FPGA(掉电即失),配合 `.ltx` 抓 ILA。
迭代阶段用它最快,验证通过后再走 A 或 B 固化。
### B 走 `/fpga_update`
**远程升级不走网页。** 网页的 Remote Update 只认 imx6 的 `*.tar.gz` 固件包,`.mcs` 传上去会被
`check_package.sh` 删掉。FPGA 走的是 TCP **1234** 上的私有协议。生成 mcs、烧写、排错的完整流程
都在 `fpga_update` skill 里,包括两个必须知道的事实:
- **擦除卡住 ≠ 还在擦。** imx6 的 `POLL_ERASER` 不看 ERROR 位,programmer 报错和正常忙碌
返回同一个 `ERASER_ING`。读设备日志的 `rstate` 才知道真相(`0x7`=已中止,`0x0`=真在擦)。
- `-imagesize 64` 和 `SpiFlashProgrammer.vhd` 里的 `cAddrUpdateStart/End` 是一对,别改。
升级完成后**断电冷启动**,让 FPGA 从 flash 重新加载,再验证。
## 三条典型工作流
**只改 RTL** → 编辑 `my_exciter.srcs/sources_1/**` → vivado-mcp `run_synthesis` +
`run_implementation` + `generate_bitstream` → `program_device` 下 bit → 抓 ILA 验证 →
满意后走 `/fpga_update` 固化。
**只改 imx6** → 编辑 `imx6/src/atsc_app/**` → 提交到 git(脚本默认打包 `HEAD`)→
```bash
python .../scripts/imx6_app.py build-deploy --tag mychange
```
→ 冷启动让 `rc.local` 拉起新 app → `imx6_app.py log` 看日志。
**FPGA + imx6 联调** → 交给 **`/fpga-imx6-flow`**。那个 skill 驱动一张 LangGraph 图,
把上电/JTAG/烧写/重启做成确定性节点,把「分析 → 判断是否达标 → 提方案 → 改 FPGA / 改 imx6」
这四步作为中断交回当前会话执行,一轮一轮迭代。PR07 明确要求走这条路做联合调试。
## 什么时候调别的 skill
| 场景 | 用 |
|---|---|
| 上电 / JTAG / 综合实现 / 抓 ILA / 下 bit | **vivado-mcp** 工具(`power_on`、`program_device`、`run_tcl`…) |
| 闭环设计-调试迭代(本 skill 的主推荐) | **`/fpga-imx6-flow`** |
| JTAG 烧 flash(golden 或砖机恢复) | **`/fpga_flash`**(flash 型号选 `w25q128bv`) |
| 单模块 RTL 仿真 / 出 testbench | **`/vivado-sim`** |
| ILA 抓出来的 IQ CSV 做频谱 / OBW / 带肩 | **`/fft-analyse`** |
| 网页操作(登录、升级、看频谱页) | **claude-in-chrome** |
| 实测频谱(N9320B 频谱仪) | `mcp__mcp_n9320b__*` 工具 |
## scripts/
| 脚本 | 用途 |
|---|---|
| `imx6_app.py` | `build` / `deploy` / `build-deploy` / `log` —— VM 交叉编译 + 推到 imx6 + 读日志 |
出 `.mcs` 和远程升级的脚本在 `/fpga_update` skill 里(`gen_update_mcs.py`、`fpga_ru.py`)。
两个脚本都 `--help` 可查。`imx6_app.py deploy` 会自动装 paramiko 2.12 到缓存目录并 re-exec
(imx6 的 dropbear 太老,paramiko 5 连不上,见下)。
## references/
按需读,别一次全读进来:
- `references/fpga.md` —— RTL 目录结构、XDC、vivado-mcp 用法、ILA/ltx 约定、已知时序告警的性质
- `references/imx6.md` —— app 源码结构、交叉编译细节、部署/日志/寄存器访问、网页
- `references/upgrade.md` —— quickboot 双镜像布局、mcs 生成的确切参数、golden 恢复
- `references/history.md` —— 历史 PR/Task 笔记索引(tuner、TSoIP、ORx、DPD、AGC 各自踩过什么坑)
## 常见坑
| 症状 | 原因 / 处理 |
|---|---|
| 远程升级后重新上电 FPGA 不跑 | 传错了文件 —— 必须是 `_update.mcs`(起始 `0x800000`),不是 `write_cfgmem` 出的基础 mcs |
| 远程升级卡在 "erasing" 不动 | programmer 已报错退出(`rstate=0x7`),imx6 的轮询不看 ERROR 位。见 `/fpga_update` |
| imx6 SSH 报 `unknown cipher` / `no acceptable host key` | dropbear 太老。用 paramiko **2.12**(`imx6_app.py` 已处理);命令行 ssh 加 `-o HostKeyAlgorithms=+ssh-rsa` |
| imx6 `open_sftp()` → `EOF during negotiation` | 设备没有 SFTP 子系统。用 `cat > file` 走 exec channel 传文件 |
| VM SSH `kex_exchange_identification: Connection closed` | VM 的 sshd 挂了,请用户 `sudo systemctl restart sshd` |
| 上电后 TX 链路死掉 | 上电后没等 `sys init over` 就连了 JTAG |
| `power_off` 卡在循环里 | 先 `USB_Blast_off` 再 `power_off`,顺序反了 |
| WNS ≈ -9 ~ -13 ns | JESD204 `init_seq_data` 的既有 false path,与功能无关,不要为它改设计 |
| `i2cget` 读 FPGA 寄存器时好时坏 | 带调试 ILA 的 bit 时序更差;且会和 app 抢总线。以生产 bit 为准,或从 app 日志读 |
## 写笔记
这个工程的约定是 `my_exciter\Notes\PRxx.md` 记**需求**,`Taskxx.md` 记**方案与实现总结**
(含验证数据和踩过的坑)。做完一轮有结论的工作,补一份 `Taskxx.md` —— 后来的人(和后来的你)
靠它避免重复踩坑。`references/history.md` 是已有笔记的索引。