在成本敏感的 Xilinx Kintex-7 FPGA 上运行的端到端 YOLOv26m 目标检测系统:GigE 工业相机进,HDMI 实时画框出,全程无 PC 参与。
End-to-end YOLOv26m object detection on a cost-sensitive Xilinx Kintex-7 FPGA: GigE industrial camera in, HDMI bounding boxes out — no PC involved.
English README 见文末 / English version at the bottom
TridentVision 把 YOLOv26m 检测网络完整部署到一块 Kintex-7 K325T 自定义板上:
海泰 HT-GE34GC 相机(GigE Vision,640×480)
│ GVSP UDP → FPGA gige/(GVCP 控制器:Discovery/配流/心跳/自愈)
▼
GVSP 解包 → DDR3 三 bank 帧缓冲(MIG x32)
▼
MicroBlaze 固件(fpga/stage3_hdmi/fw/src/main.c)
├─ crop PL(96×96 检测输入窗)
├─ 推理引擎(rtl/:85 job 静态程序表,AXI4 主控 + MAC 阵列 + ROM DMA 直灌)
├─ snap_pp PL:CLS 直灌 + BOX 位精确整数乘
├─ finish:topK/NMS/decode(可切块增量堆排序,藏进引擎等待环)
└─ stamp_dets:白框 + FPS OSD 叠加
▼
frame_reader → TMDS(rgb2dvi)→ HDMI 640×480@60
- 模型:yolo26m 的 FPGA 友好重构版(REARCH-v1)——92 层 / 85 job,全部层落入引擎六种原生算子闭集(3×3/1×1 conv、conv s2、ADD、FC、maxpool5);403.3M MACs(较官方 26m -65%),int8 权重 10.19MB(-67%),mAP@0.5 = 0.2066(96² 口径,教师 0.2229)
- 训练:int8 QAT 从第一天介入(禁后训练量化),COCO 118,287 图 / 100 epochs / ~11.5h
- 部署:QSPI flash 固化位流+固件,TF 卡存权重与 ROM 表,上电自启,断电解缆产线形态
- 验证:每一级提速后硅上 82/82 点 bit-exact;C 参考模型与 RTL 逐位一致;四帧闸门 134 点 ×4 帧全绿
| 自定义板 | 识别输出 |
|---|---|
![]() |
![]() |
- 纯 FPGA 推理:无 GPU、无电脑、无外挂 CPU 板;MicroBlaze 仅做调度与画框
- 上电自启:QSPI flash 自配置 ~2.6s → TF loader 读卡(v3 镜像 11.4MB,超级块+区段表+CRC32)→ 检测流水线
- 链路自愈:GVSP 看门狗(流静默 3s 检出,复电 ~10.3s 零干预自愈);GUARD 固件病态防护(相机楔死时冻结画框防误导,见 §10 故障案例)
- 位精确可信:FPGA 定点推理与 C 参考模型逐位一致,全部验证套件 100% 通过(见 §3)
- IP 保护参考实现:芯片 DNA 绑定 license(dna_license.v + keygen),教学向全量公开(见 §9)
- 可复现:全部构建脚本、测试台、资产生成器、实测报告入库;图表由
docs/scripts/gen_charts.py一键再生
| 资源 | 用量 | 利用率 |
|---|---|---|
| Slice LUTs | 113,808 / 203,800 | 55.84% |
| Slice Registers | 98,740 / 407,600 | 24.22% |
| BRAM Tile | 346.5 / 445 | 77.87% |
| DSP48 | 387 / 840 | 46.07% |
| Slice | 41,596 / 50,950 | 81.64% |
时序:rrC 基线 WNS +0.088 / WHS +0.051 / 0 失败端点(impl 实测,见 docs/reports/hdmi_timing_impl.rpt)。
| 件 | 型号/规格 | 必需性 |
|---|---|---|
| FPGA 板 | 自定义 Kintex-7 板(xc7k325tffg676-2),原理图/PCB 见 hardware/gw2ar_pcb/(GW2AR 评估板)与 docs/GW2AR_*.md;或 KC705 + ip_core/(见 §7 构建路径) |
必需 |
| 相机 | 海泰 HT-GE34GC-T1-C(GigE Vision,640×480),网线直连板上网口(勿经交换机) | 必需 |
| TF 卡 | ≥4GB SDHC,刷 TF 镜像(权重+ROM 表) | 必需 |
| 显示器 | HDMI 640×480@60 | 必需 |
| 采集卡 | 任意 HDMI 采集卡(抓屏取证用) | 可选 |
| JTAG | Xilinx 下载器(开发/烧录用;产线运行不需要) | 开发期 |
| 目录 | 内容 |
|---|---|
rtl/ |
加速器引擎 RTL(现行构建 11 个模块 + legacy 4 个)+ romdma 单元测试台与测试向量 |
fpga/stage3_hdmi/ |
主工程:顶层/display/gige/tfload 源码、约束、tmds_ip(rgb2dvi)、固件 src、仿真测试台、Vivado 构建 tcl、板级调试工具 |
ip_core/ |
可封装 IP 核形态:rtl/(含 dna_license.v)、sim/(结构审计 + license 测试台)、deliverable/(客户集成指南、KC705 例程、keygen 与厂商操作手册——教学向公开) |
training/ |
训练/QAT/导出全链 Python(patches.py 运行时 monkey-patch 实现全部模型改动,不改 ultralytics 本体) |
c_model/ |
C 参考模型与 bit-exact 验证链(yolo26.c 等)、量化分析脚本、RTL 对拍向量 tb_vectors/ |
assets/ |
部署资产(int8 权重镜像 mem_weights.bin 10MB、rom_blob/rom_rle、输入帧 mem_input.bin) |
tools/ |
相机模拟器、ILA/pcap 分析、流实验脚本;stage3_legacy/(含 gen_stage3_assets 资产生成器与 run_xsct 基建);sim_gvsp/ |
hardware/gw2ar_pcb/ |
GW2AR-LV18-QN88C8 自定义板 Altium 源文件(4×SchDoc + PcbDoc) |
docs/ |
全部设计文档、教程、实测报告、图表(docs/images/)与图表生成器(docs/scripts/) |
specs/ |
MACs 核算脚本与输出 |
环境:Vivado 2024.1(含 Vitis/xsct)、Python 3(训练需 CUDA + PyTorch + ultralytics,见 training/README.md)、Icarus Verilog(仿真,可选)。
:: 1) FPGA 友好重构模型训练 / QAT int8(~11.5h,可 ckpt 续跑)
cd training && python qat.py
:: 2) 导出 int8 权重镜像 + 6 门禁验证(C vs numpy bit-exact、MACs 对账、ISA 检查…)
cd export && python rearch_export.py
:: 产物:rearch_int8.bin(10.19MB,已入库一份在 training/export/)详见 docs/training_export_guide.md。
:: 由 export 产物生成 assets/(mem_weights.bin / rom_blob.bin / rom_rle.bin / mem_input.bin)
python tools/stage3_legacy/gen_stage3_assets_rearch.py
:: 生成 TF 卡镜像并用 Win32DiskImager 刷入(详版:docs/deploy_guide.md 与 docs/tf_card_flash.md)cd fpga/stage3_hdmi
"C:\Xilinx\Vivado\2024.1\bin\vivado.bat" -mode tcl -source build_stage3_hdmi.tcl
:: 工程从零重建(BD + MIG + 引擎 RTL 引用 rtl/),耗时约 78min- 开发期(JTAG):
tools/下run_xsct.py+ 烧板脚本;每次换 bit 必走全量重灌流程(见 §8 已知坑 #1) - 产线(QSPI 固化):write_cfgmem 生成 mcs → program_flash → 上电自配置 ~2.6s
- 上电时序锚点(V1.0 固化版实测,REARCH 版链路相同):0–26s 黑屏自举(正常)→ ~26s 相机画面上屏 → ~33s 识别画框叠加
上电后读 FP0/FP1/FP2 得 96bit 指纹 → ip_core/deliverable/vendor/keygen/keygen.bat <指纹hex> → 写 KEY0/KEY1/KEY2。详版见 §9 与 ip_core/deliverable/customer/doc/TridentVision_IP核客户集成指南.md。
| 文档 | 内容 |
|---|---|
| docs/deploy_guide.md | 部署指南:接线、TF 卡烧录、QSPI 固化、上电时序、验收 |
| docs/training_export_guide.md | 训练与导出指南:依赖、QAT、6 门禁导出验证链 |
| docs/debug_guide.md | 调试指南:ILA、UART 日志字段、状态页轮询、GUARD 状态位 |
| docs/optimization_roadmap.md | 优化路线图与收益估算(见 §11 摘要) |
| docs/troubleshooting_index.md | 故障案例集索引(GigE 调试总结 19 章 + 各文档坑记录) |
| ip_core/deliverable/customer/doc/TridentVision_IP核客户集成指南.md | KC705/IP 核集成指南(脱敏版) |
| docs/gige_debug_summary.md | GigE Vision 调试总结(19 章,含相机病态案与 GUARD 设计) |
| docs/REARCH_V1_OPTIMIZATION_SUMMARY.md | REARCH-v1 优化全程(六杠杆 + 显示税战役数据源) |
| docs/REARCH_FPS_DISSECTION.md | 帧率解剖(含固化手册、A200T 降档评估) |
| docs/YoloV26M_FPGA_V1.0_总结.md | V1.0 全程总结(0.2→3.2fps 十六跳、验证方法学、坑与教训) |
KC705 构建路径(D5 说明):ip_core/deliverable/customer/example_kc705/ 的构建脚本以 DCP 例化 IP 核。本仓库不带 dcp——两条路:① 从 Release 页下载 tv3_ip_core.dcp;② 用 ip_core/rtl/ 源码在 Vivado 中自行 package_ip 生成。
- "换 bit 必踢相机":烧板瞬态 MIG 刷新中断 → DDR 权重/ROM 区 14~16% bit 翻转,且相机错过 GVCP 发现窗会楔死。每次 JTAG 换 bit 后必须全量重灌资产并重启/踢相机(烧板 SOP 见 docs/deploy_guide.md §5)。
- JTAG 轮询污染:高频采样挤占 AXI 把帧 417→495ms——观测者效应真实存在,墙钟测量只能稀疏采样。
- Windows 路径上限:Vivado 工程深路径 + 长中文目录名易触 MAX_PATH——工程放短路径根目录。
- XDC 大小写敏感:
get_ports名与 HDL 大小写不一致时静默不生效,时序约束形同虚设——elab 后必查约束覆盖率。 - DCI 级联:多 bank DCI 级联链配置错误会导致 IO 标准隐式降级——布板与约束需交叉核对。
- 写后读回要在另一个地址空间做(MMU 冤案教训):LMB 自洽的"读回校验通过"全是假象。
- 采集类判据先验活再判读:相机死掉时全同帧会让"三判据全绿"(空绿陷阱)。
本仓库全量公开一套芯片 DNA 绑定 license 体系,作为 FPGA IP 保护的教学样本:
芯片 DNA(57bit, 不可读改写)
│ 硬件上电自动(约 1µs):
▼
指纹 FP = PRF₂₄(DNA ⊕ SALT1) ← 96bit,锁定态也可读
├─ 正式 key = PRF₂₄(FP ⊕ SALT2 ⊕ 0xF1)
└─ 试用 key = PRF₂₄(FP ⊕ SALT2 ⊕ 0x7E) (4000 帧配额,帧完成自动 -1,支持持久化)
- RTL:
ip_core/rtl/dna_license.v(PRF ARX 24 轮 + 种子构造 + 比对门控) - 钥匙机:
ip_core/deliverable/vendor/keygen/(prf_ref.py与 RTL 逐位一致,仿真对拍验证) - 流程文档:
ip_core/deliverable/vendor/厂商操作手册.md、客户侧TridentVision_IP核客户集成指南.md - 说明:文档与示例中的指纹/key 值均已替换为占位符(如
0123456789ABCDEF01234567);本体系防君子不防有资源对手,公开目的是教学参考。
相机半锁死案(docs/gige_debug_summary.md 第十九章):消费端消失 → 相机流引擎楔死为 1.3fps 涓流(PC 直连 98fps 满血,排除相机硬件)。固件侧落地 GUARD 病态防护:停驻率 EMA(>2048 进入 / <1024 解除回差)→ 病态期冻结画框(SCRATCH[32/35/36] 可观测),实测病态期 shown=0、输入框消退、识别维持 10.2fps 不雪崩。完整案例索引见 docs/troubleshooting_index.md。
| 项 | 预计收益 | 工作量 | 依据 |
|---|---|---|---|
| add/ups 通路 burst 化 | +0.4~0.5 fps | 2-3 人天 | REARCH 总结 §6#3,已评估未实施 |
| 显示税残量回收(snapshot/stamp 调度) | 残量 ~15ms 中的部分 | 待评估 | §7.7 |
| 引擎 73.6ms 本体(下一瓶颈) | 上限取决方案 | 大 | §7.7:显示税打完后只剩引擎 |
| 杠杆 F:AXI master 多 outstanding | 射程内 ~34.5ms 已被预吃大半,ROI 边际 | 暂缓 | §2.3 裁决记录(64 态直方图分解) |
| 纯逻辑化 v2(去 MicroBlaze) | 省 ~1.25K LUT + 16 BRAM36 | 待拍板 | §6#5 |
| A200T 降档(砍 GigE 栈 + 瘦身) | slice 122.7% → 中值 96.9%,有条件可部署 | 需实跑 impl 终验 | FPS_DISSECTION 附录 E |
详版:docs/optimization_roadmap.md。
本项目整体以 AGPL-3.0 发布(见 LICENSE),包括全部自研 RTL、固件、C 模型与训练脚本。
| 第三方 | 许可 | 使用方式 |
|---|---|---|
| ultralytics(yolo26) | AGPL-3.0 | 训练依赖,未修改其源码——全部模型改动由 training/patches.py 运行时 monkey-patch 实现;请自行按其许可获取 |
| yolo26m.pt 预训练权重 | AGPL-3.0 | 不入 git 树,随 Release 附件分发 |
| stb_image / stb_image_write | Public Domain | c_model/ 内图片读写 |
| rgb2dvi(Digilent) | 见 fpga/stage3_hdmi/tmds_ip/ 内版权头 |
HDMI TMDS 输出 IP |
Release 附件(不入 git 树):yolo26m.pt(44MB)、tv3_ip_core.dcp(14MB,KC705 集成用)。
见 CITATION.cff。引用格式:
TridentVision: End-to-end YOLOv26m object detection on Kintex-7 FPGA (2026). AGPL-3.0.
An end-to-end object detection pipeline on a cost-sensitive Xilinx Kintex-7 (xc7k325t) board: GigE Vision camera in, HDMI with real-time bounding boxes out — fully standalone, no PC.
- Model: FPGA-friendly re-architecture of yolo26m (REARCH-v1) — 92 layers / 85 jobs, all ops inside the engine's six-op ISA (3×3/1×1 conv, conv-s2, ADD, FC, maxpool5). 403.3M MACs (-65% vs official 26m), 10.19MB int8 weights (-67%), mAP@0.5 = 0.2066 @96² (teacher 0.2229).
- Training: int8 QAT from day one (no post-training quantization), COCO 118k images, 100 epochs, ~11.5h.
- Deployment: bitstream+firmware in QSPI flash, weights on TF card, power-on self-start (~2.6s self-configuration), offline production-line form factor.
- Verification: silicon bit-exact 82/82 after every speedup lever; C reference model bit-identical to RTL; 4-frame gate 134 points ×4 frames all green.
| Metric | Value |
|---|---|
| Production fps (HDMI + boxes + OSD) | 9.679 fps (baseline 7.756 → +24.8%, display-tax campaign) |
| Validation-line fps (no display) | 12.897 fps (0.831 → 15.5× via six levers) |
| Engine time | 73.6 ms/frame (5.524M cyc @75MHz) |
| K325T utilization | LUT 55.84% / FF 24.22% / BRAM 77.87% / DSP 46.07% / Slice 81.64% |
| Timing (rrC) | WNS +0.088 / WHS +0.051 / 0 failing endpoints |
| Boot chain | QSPI self-config ~2.6s → TF loader (v3 image 11.4MB) → detection |
All charts live in docs/images/ and regenerate via python docs/scripts/gen_charts.py (measured data hard-coded with per-value source annotations; QAT curve from docs/scripts/qat_epoch_log.csv).
rtl/ accelerator engine RTL · fpga/stage3_hdmi/ main project (top/display/gige/tfload RTL, constraints, firmware, sim testbenches, Vivado tcl, board-debug tools) · ip_core/ packageable IP core (incl. dna_license.v, KC705 example, keygen) · training/ training/QAT/export chain · c_model/ bit-exact C reference + tb vectors · assets/ deployment binaries · tools/ misc + asset generators · hardware/gw2ar_pcb/ custom board Altium sources · docs/ all design docs, tutorials, reports, charts · specs/ MACs accounting.
Prerequisites: Vivado 2024.1 (with Vitis/xsct), Python 3 (PyTorch + CUDA + ultralytics for training), Icarus Verilog (optional, for simulation).
- Train & export:
cd training && python qat.py→cd export && python rearch_export.py(6-gate verification: C-vs-numpy bit-exact, per-layer MACs, ISA check…). - Assets & TF image:
python tools/stage3_legacy/gen_stage3_assets_rearch.py, then flash the TF image (details:docs/deploy_guide.md,docs/tf_card_flash.md). - Build bitstream:
vivado -mode tcl -source fpga/stage3_hdmi/build_stage3_hdmi.tcl(~78 min full build). - Burn & boot: JTAG for development (full asset re-flash after every bit change — see known pitfall #1); write_cfgmem → QSPI mcs for production. Power-on timeline anchor (V1.0 fixed image): ~26s camera picture, ~33s detection boxes.
- License (educational): read FP0/1/2 →
keygen.bat <fp-hex>→ write KEY0/1/2 (seeip_core/deliverable/docs).
Deploy guide · training/export guide · debug guide (ILA, UART fields, status-page polling, GUARD bits) · optimization roadmap with ROI estimates · troubleshooting case index (19-chapter GigE debug summary) — all under docs/, bilingual (Chinese primary, English summaries).
- "Every bit change must kick the camera": configuration transients corrupt 14–16% of DDR weight/ROM bits and the camera misses the GVCP discovery window → full asset re-flash + camera power-cycle required.
- JTAG polling pollutes AXI (observer effect: frame 417→495ms under dense sampling) — sample sparsely.
- Windows MAX_PATH with deep Vivado paths; XDC case-sensitivity silently voids constraints; DCI cascade misconfig silently degrades IO standards.
- Verify write-backs in a different address space (the "MMU wrongful-conviction" lesson).
add/ups burst-ification +0.4~0.5 fps (2–3 person-days) · display-tax residue ~15ms · engine 73.6ms becomes the next wall · multi-outstanding AXI master deferred (marginal ROI after histogram decomposition) · pure-logic v2 (−1.25K LUT, −16 BRAM36) · A200T cost-down path evaluated (96.9% slice median, conditional). Details: docs/optimization_roadmap.md.
Overall AGPL-3.0 (see LICENSE), covering all original RTL, firmware, C model and training code. Third parties: ultralytics (AGPL-3.0, used unmodified via runtime monkey-patching in training/patches.py), yolo26m.pt weights (AGPL-3.0, Release asset), stb_image (public domain), rgb2dvi (Digilent, see license header in fpga/stage3_hdmi/tmds_ip/). Release assets (not in git): yolo26m.pt (44MB), tv3_ip_core.dcp (14MB).
The DNA-bound license protection (ip_core/rtl/dna_license.v + keygen) is published for educational purposes; all fingerprint/key values in docs are placeholders.










