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

9.2 KiB
Raw Blame History

name, description
name description
smod_atsc_dev 在 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)→

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 是已有笔记的索引。