Update FPGA and Vivado skills

This commit is contained in:
Myfro9
2026-07-14 18:18:17 +08:00
parent d20ec12fee
commit bceafcd58c
14 changed files with 1707 additions and 14 deletions
+81
View File
@@ -0,0 +1,81 @@
# FPGA 侧(my_exciter / RU_golden)
## 工程
| | my_exciter | RU_golden |
|---|---|---|
| xpr | `E:\Xilinx_design\smod\SMOD_ATSC\my_exciter\my_exciter.xpr` | `...\RU_golden\RU_golden.xpr` |
| top | `smod_top`(`my_exciter.srcs/sources_1/top/smod_top.v`,~2300 行) | `RU_golden_top` |
| 作用 | ATSC 激励器全功能 | 打底镜像:网口 + quickboot 自烧,用来兜底和支撑远程升级 |
| 器件 | xc7a200tfbg676-2 | 同左 |
`my_exciter` 目录本身是 **git 仓库根**(`imx6/` 也在里面)。RU_golden 的 xpr 引用了
my_exciter 里的少数源文件(`ts_lock_top.vhd`、`sdram_tsoip_top.vhd`),改动时留意。
## RTL 目录(`my_exciter.srcs/sources_1/`)
| 目录 | 内容 |
|---|---|
| `top/` | `smod_top.v` 顶层 + 时钟/AGC/DA 前处理/ORx 抽取等杂项 |
| `atsc_mod_xip/` | 8VSB 调制核(加密 IP) |
| `dpd/` | 数字预失真 |
| `txagc/` | 发射 AGC |
| `asi_pre/`, `dvb_asi/`, `ts/` | ASI / TS 输入与包同步(`src_preproc`、`spi_lock_det`) |
| `tsoip/`, `tsoip_atsc/`, `udp/`, `sdram/` | TS over IP 收发与缓存 |
| `tuner/` | Sony CXD2878 tuner 的 TS 接口(`TUN_D[7:0]/TUN_VLD/TUN_CLK`) |
| `quickboot/` | `SpiFlashProgrammer.vhd` + `SpiSerDes.vhd` + `spi_slave32.v` —— 远程升级的 FPGA 侧 |
| `i2c/` | imx6↔FPGA 的寄存器桥 |
| `gps/`, `uart/`, `misc/`, `bd_cfg/`, `coef/`, `ip/` | 其余 |
约束在 `constrs_1/new/`:`smod_ioplanning.xdc`(SMOD 板的引脚,**这块板用这个**)、
`project_ioplanning.xdc`(旧板,别混用)、`timing.xdc`、`timing_cleanup_120m.xdc`、
`bitstream.xdc`、`debug.xdc`(当前为空,ILA 用 IP 例化而非 XDC 标记)。
## 用 vivado-mcp 干活
典型顺序(工具名即 `mcp__vivado-mcp__*`):
```
start_session(project=<xpr>) # 打开工程
→ verilog_compile_check # 改完 RTL 先做语法检查,比跑综合快得多
→ run_synthesis
→ get_critical_warnings # 综合后立刻看,别等到实现完
→ run_implementation
→ generate_bitstream
→ get_timing_report / get_utilization_report
→ power_off → USB_Blast_off → power_on → (等 sys init over) → USB_Blast_on
→ program_device # 下 bit(掉电即失)
```
其它常用:`run_tcl` / `safe_tcl`(任意 Tcl)、`get_run_progress`(长任务轮询)、
`get_ip_status` / `inspect_ip_params`、`xdc_lint` / `xdc_auto_fix`、`get_io_report`。
综合+实现在这个工程上要 **20~40 分钟**。改一行就重跑之前,先用 `verilog_compile_check`。
## ILA
`smod_top.v` 里 ILA 是**手工例化的 IP**(不是 `mark_debug`)。历史上用过 `ila_eth2`、
`ila_2`、`ila_3`、`ila_adrv9009_fb`;当前活跃的是 `u_ila_adrv9009_rx`(复用
`ila_adrv9009_fb` IP,探针宽度 16,16,1,8,1,1,1,8,8,8,8,5)。
要换探针就直接改那个例化的 probe 连接。**探针宽度必须和 IP 里配的一致**,否则综合报错。
需要新宽度就改 IP 或换一个 ILA IP。
抓波形要 `.ltx`(`impl_1/smod_top.ltx`)。归档时 `.bit` / `.ltx` / `.mcs` 三件套用**同一个 tag**
放进 `bitstream/`,否则下次想复现就对不上号了。ILA 导出的 CSV 交给 `/fft-analyse` 做频谱。
**固化前把调试 ILA 去掉**,重新实现出干净的生产 bit:ILA 吃资源、恶化时序,还会和 imx6
抢寄存器总线。
## 时序
`get_timing_report` 上 WNS 常年在 **-9 ~ -13 ns**,路径落在 JESD204 TX 的
`init_seq_data`(`jesd204_phy_1lane_38j82_refclk` group)。这是基础设计里**既有的
初始化序列 false path**,与 ATSC 数据通路无关 —— JESD 链路实测能起来,RF/调制/tuner 都正常。
不要为了这个数字去改设计。真正要盯的是你改动那部分的时钟域和 CDC。
## 出 mcs
走 `/fpga_update` skill。一句话:远程升级要的是 `_update.mcs`,不是 `write_cfgmem` 的直接产物;
而且它走 TCP 1234,不走网页。
+35
View File
@@ -0,0 +1,35 @@
# 历史笔记索引(`my_exciter\Notes\`)
约定:**`PRxx.md` = 需求**(用户提出的要做什么),**`Taskxx.md` = 方案 / 实现总结**
(怎么做的、踩了什么坑、验证结论)。`discussNN-*.md` 是过程讨论。
遇到相关主题**先读对应的 Task 文件**——里面的结论往往能省掉一整轮硬件迭代。
| 主题 | 需求 | 方案 / 总结 | 结论要点 |
|---|---|---|---|
| 从 EMV7.1 移植到 SMOD | `PR00.md`、`PR01.md` | `Task00.md`、`Task01.md` | 引脚重排到 `smod_ioplanning.xdc`;IO bank / 自由引脚勘查脚本也在 Notes 里(`task01_*.tcl`) |
| ADRV9009 JESD + SPI 寄存器核对 | `PR02.md` | `Task02.md` | JESD204B TX/RX lock status 寄存器位置 |
| TSoIP(网口 2 收 IP 流取 TS) | `PR03.md` | — | 根因见 memory `tsoip-root-cause-0x50` |
| Tuner(473 MHz RF → TS → 调制核) | `PR04.md` | `Task04.md` | demod 是 **Sony CXD2878 + FREIA**,不是 MN88436;移植 EMV9.3 的 `sonytuner/`;ILA 实测 19.41 Mbps、`ts_lock_a=1`、0x47 间隔 188 |
| ATSC 信号质量分析(RX1 路) | `PR06.md` | `Task06.md` | 用 RX1 接收自发信号,算带肩 + 8VSB 星座 + SNR,网页 `sys_spectrum.html` 显示 |
| 改用 ORx→DPD 40 MHz 反馈 | `PR06-1.md` | `Task06-1.md` | 反馈通道换成 ORx |
| ORx/RX1 双通道可切换 + DPD 内部 AGC | `PR06-2.md` | `Task06-2.md` | 共用滤波下采样;大量频谱截图见 `PR06-2_*.png`,索引在 `PR06-2_频谱截图索引.md` |
| 本 skill 的由来 | `PR07.md` | (本 skill) | 要求:SMOD ATSC 开发总入口,联调走 `/fpga-imx6-flow` |
## 其它散落资源
- `Notes/*.png` —— 历次频谱 / 星座 / 波形截图,文件名带 iter 号,配合 Task 文件看
- `Notes/create_ila_adrv9009_fb.tcl` —— 建 ILA IP 的 Tcl
- `Notes/task01_*.tcl` —— IO / DSP / 未约束端口的勘查脚本
- `Notes/workflow_state.db`、`workflow_threads.json` —— fpga-imx6-flow 的 LangGraph 状态
- `RU_golden/skills/*.py` —— 早期 RMII/GMII 抓包分析脚本(网口调试用)
- `bitstream/ila_*.csv`、`orx_*.csv` —— 历次 ILA 导出,交给 `/fft-analyse` 复现频谱
## 已固化的经验(别重新踩)
- 上电时序铁律;上电后等 `sys init over` 再连 JTAG,否则 TX 死。
- WNS -9~-13 ns 是 JESD204 `init_seq_data` 的既有 false path,与功能无关。
- imx6 dropbear 老:paramiko 2.12 + `cat >` 传文件(无 SFTP)。
- 设备上 `imx_atsc_app.rx1` 和 `M=2/lane 0x04` 变体会打断 TX;git `HEAD` 的版本是好的。
- 远程升级走 TCP 1234(不是网页!),只能传 `_update.mcs`,传错文件会导致冷启动后 FPGA 不跑。
- 远程升级"卡在擦除"通常是 programmer 已报错(rstate=0x7),imx6 轮询不看 ERROR 位。见 `/fpga_update`。
- 带调试 ILA 的 bit 下 `i2cget` 读 FPGA 寄存器不可靠。
+84
View File
@@ -0,0 +1,84 @@
# imx6 侧(atsc_app)
## 源码
`E:\Xilinx_design\smod\SMOD_ATSC\my_exciter\imx6\src\atsc_app`(Makefile 在这一层):
| 目录 | 内容 |
|---|---|
| `main.c` | 起线程:`fpga_upgrade_task`、`tcp_task`、`web`、`lcd`、`gps`… |
| `bsp/` | 板级:`i2c_drv.c`、`fpga.c`(FPGA 寄存器读写)、`eeprom.c`(配置)、`dac38j82.c`、`dpd_proc.c`、`isys_config.c` |
| `talise/`, `adrv9009/`, `adi_hal/` | ADI ADRV9009 驱动 |
| `sonytuner/` | Sony CXD2878 + FREIA(CXD6821) 解调驱动(从 EMV9.3 移植,见 PR04) |
| `task/` | `upgrade.c`(软件包升级)、`tcp_task.c`、`iweb_task.c`、`tsoip.c`、`iq_rx.c` |
| `inc/` | 头文件;`fpga.h` 里 `FPGA_UPGRADE_I2C_REG_ADDRES = 0xE0` |
同级还有 `imx6/src/web/`(cgi + www 页面,含 `upload.cgi` 远程升级入口)。
## 交叉编译
工具链在 VM `bowei@192.168.223.128`(密码 `lr7402`):
```
/opt/fsl-imx-x11/4.1.15-2.0.0/environment-setup-cortexa7hf-neon-poky-linux-gnueabi
```
流程(`scripts/imx6_app.py build` 已封装):
1. Windows 侧从 git 打包源码 —— **用 `HEAD` 而不是工作区**,这样构建的东西可追溯:
`git -C my_exciter archive --format=tar -o app.tar HEAD:imx6/src/atsc_app`(约 13 MB)
2. SFTP 上传到 VM,解到 **`~/atsc_head_build`**(一个干净目录;不要碰 `~/atsc_tsoip_build/` 之类的旧目录)
3. `bash -lc 'source <envsetup>; cd ~/atsc_head_build && make'` → 产出 `imx_atsc_app`(~2.9 MB ELF)
4. SFTP 取回 Windows
VM 的 sshd 是现代版本,paramiko 5 / OpenSSH 都能连。若报
`kex_exchange_identification: Connection closed`,是 VM 的 sshd 挂了,请用户 `sudo systemctl restart sshd`。
## 部署到设备
设备 `192.168.1.143`,`root` / `anywavecom`。**它的 SSH 是老 dropbear**,有两个坑:
1. **算法太老**:paramiko 5 会报 `unknown cipher` / `no acceptable host key`。
要用 **paramiko 2.12**(有 TripleDES / aes-cbc / ssh-rsa):
`python -m pip install --target <dir> paramiko==2.12.0`,然后 `PYTHONPATH=<dir>` 跑。
命令行 ssh 则加 `-o HostKeyAlgorithms=+ssh-rsa`。
2. **没有 SFTP 子系统**:`open_sftp()` 直接 `EOF during negotiation`。传文件走 exec channel:
```python
ch = client.get_transport().open_session()
ch.exec_command("cat > /aw/anywave/app/imx_atsc_app_head")
ch.sendall(open(local_bin, "rb").read())
ch.shutdown_write(); assert ch.recv_exit_status() == 0
```
(另一条老路是 SSH 反向端口转发 + 设备侧 `wget`,见 Task04;现在没必要了。)
部署顺序 —— **先落一个新名字,验证 md5,再覆盖 active**,这样传输失败不会毁掉能跑的 app:
```
cat > /aw/anywave/app/imx_atsc_app_head
chmod 755 imx_atsc_app_head
md5sum 对比
cp -a imx_atsc_app_head imx_atsc_app # 覆盖 active
```
`scripts/imx6_app.py deploy` 就是这个顺序。已知好用的备份是 `imx_atsc_app.bak_pre_rx1`。
改完 app 要**冷启动**(断电重启,遵守上电时序)让 `rc.local` 拉起新进程。
## 观察设备
- 日志:`/var/module_log/imx_atsc_app.log`。健康标志:`TALISE_radioOn`、`fb init state ok`、
`fpga[0xBB]=0x03`(sync=1 / tvalid=1)。`imx6_app.py log` 直接拉。
- 配置:`/aw/anywave/cfg/exc_cfg.conf`,`[BLK_SYS_PARA] reg50` 选输入源
—— `0`=Tuner,`1`=TS,`2`=EAS,`3`=TSoIP。
- 网页:`http://192.168.1.143`(`sys_rf.html`、`sys_ts.html`、`sys_set.html`、
`status_info.html`、`log_output.html`、以及远程升级的 `upload.cgi`)。
- 串口控制台(COM 号见 `~/fpga_imx6_flow.json` 的 `ports.imx6`,逐机而异、不入库)能用,但会自动登出、比较飘。**优先走网络 SSH**读日志和跑命令。
- 直接读 FPGA 寄存器可以 `i2cget`,但它会和 app 抢总线;带调试 ILA 的 bit 下更不可靠。
以 app 日志为准,或者临时停掉 app。
## 已知不能用的构建
设备上的 `imx_atsc_app.rx1`、以及任何 `M=2 / lane 0x04` 的变体**会打断 TX**。
git `HEAD` 的版本是 RX1-on-framerA(`M=4` / lane `0x03` / RX1RX2)+ TX 正常的已知好版本。
+24
View File
@@ -0,0 +1,24 @@
# 远程升级 / Flash 布局
**这块内容的唯一真源是 `fpga_update` skill。** 要生成 `_update.mcs` 或者把它烧进板子,
直接用那个 skill,别在这里另起炉灶。
- `~/.claude/skills/fpga_update/SKILL.md` —— 流程
- `~/.claude/skills/fpga_update/references/quickboot.md` —— flash 布局、切换字兜底、`-imagesize 64` 的由来
- `~/.claude/skills/fpga_update/references/protocol.md` —— TCP 1234 协议、以及 DPD 污染升级数据流的缺陷
三件容易记反的事:
1. **FPGA 的远程升级不走网页。** 网页的 Remote Update 只认 imx6 的 `*.tar.gz` 固件包;
`.mcs` 传上去会被 `check_package.sh` 直接删掉。FPGA 走 TCP **1234** 的私有协议
(原厂工具 `tools/Xfpga_ru.exe`,替代品 `fpga_update/scripts/fpga_ru.py`)。
2. **升级前必须关掉 DPD**,否则 DPD 的 SPI1 流量会混进镜像,CRC 校验失败。
3. **`_update.mcs` 不能 JTAG 烧写**,`_initial.mcs` 也不能远程升级。首次装机 / 救砖走
`/fpga_flash`(flash 型号 `w25q128bv`,烧 `RU_golden/bitstream/golden_design_initial.mcs`)。
## 调试期的第三条路
`program_device` 直接把 `.bit` 下到 FPGA,掉电即失。迭代验证用它最快 —— 不碰 flash,
配 `.ltx` 就能抓 ILA。功能确认后再走远程升级固化。
固化用的 bit 要**去掉调试 ILA 重新实现**:ILA 吃资源、恶化时序,还会和 imx6 抢寄存器总线。