0. 初衷:从算法到硬件的认知演进
我的历程:算法 → RTL → 算法 & RTL。构建起这座桥,实现双向互译,直到达到'写算法时心中有电路,写 FPGA 时心中有算法'的境界。

阶段 1:算法的'原教旨主义'
早期与许多算法工程师一样,停留在 MATLAB/Python/C 语言的抽象层面。图像是 imread() 返回的完美矩阵,处理是调用 conv2() 或 cv2.GaussianBlur() 等函数。数据被视为静止、无限且免费的:内存不足就加 DIMM,算得慢就等待,边界处理依赖 padarray 或 cv2.BORDER_REFLECT 自动完成。
阶段 2:感知 FPGA RTL 实现的成就感与艺术
初识 FPGA 代码时充满困惑:为何要手动计算地址?为何不能直接用 for 循环遍历整图?always @(posedge clk) 究竟意味着什么?这种认知撕裂感源于懂算法的'数学语言',却不懂硬件的'电路语言'。
直到独立完成第一个 Line Buffer 并调通图像空间滤波算法,才顿悟:硬件不是在'实现'算法,而是在'演绎'数据流。在资源、带宽与 PPA(Power, Performance, Area)的约束下进行优化,能深刻感知 FPGA 实现的艺术。
阶段 3:建立'互译'能力 如今能在 MATLAB 与 Vivado 之间自由穿梭,核心在于建立了'中间表示'(Intermediate Representation):看到卷积,脑中浮现的是滑动窗口数据流图(Line Buffer → Shift Register → MAC 树);看到硬件流水线延迟(Latency),能立刻映射到算法的帧缓冲需求;编写 C 定点代码时,脑中同步运行 Verilog 波形与 MATLAB 浮点参考,确保各级误差可控。这种'双向翻译'能力是成为系统架构师(System Architect)的元技能。
1. 方法论:跨界翻译的核心
本课程聚焦方法论本身,旨在打通'算法思维'与'硬件思维'的转换通道。这是一门'跨界翻译'指南:将数学语言转化为电路语言,并用流水线思维反哺算法设计。
2. 核心工作流:三级跳验证
- MATLAB 浮点原型(验证算法正确性)
- 手动定点化 C 模型(验证数值精度与范围)
- 时序展开 Verilog/RTL(验证硬件可行性与资源消耗)
关键洞察:C 定点化不是过渡步骤,而是精度验证的黄金标准。MATLAB 算对而 C 算不对,必是定点化逻辑有误;C 算对而 RTL 算不对,必是时序或流水线设计有误。
3. 思维架构与核心机制
3.1 两种思维方式的碰撞
- 算法人员误区:'先计算完整图像的梯度,再做非极大值抑制。'
- FPGA 人员误区:'只需将公式中的乘加运算全部映射到 DSP48 即可。'
- 正确认知:
- 空间域:图像是数据流,而非静态矩阵(除 DDR 缓存场景外)。
- 时间域:每个时钟周期必须产出结果或满足目标吞吐率,不可依赖'迭代收敛'过程。
- 精度域:硬件中没有
float,只有wire [N:0]与$signed()的精度博弈。
- 对比实验:以 3×3 Sobel 为例。算法版使用卷积函数、边界补零、整帧计算;硬件版采用 Line Buffer + 滑动窗口、边界复制、像素级流水线。
3.2 跨越 GAP 的三大核心机制
3.2.1 数据流架构(Stream Processing)
相机本质是 CMOS 传感器通过 LVDS/MIPI 输出一维数据流,而非二维数组。
- Line Buffer:利用 BRAM 缓存若干行,实现'垂直方向的时间换空间'。
- Kernel 对齐:通过 Valid 信号配合,使 3×3 窗口在流式数据上正确滑动。
- 乒乓与反压:当下游处理慢于上游时,通过 TREADY 信号传递反压机制。
- 实战理解:对比'流式直方图均衡'(需全图统计)与'流式自适应阈值'(局部窗口即可),理解算法对数据流的天然适配性。
3.2.2 存储层次设计(Memory Hierarchy)
三级存储模型:
- Register(寄存器):存储当前窗口像素,支持并行访问,零延迟。
- BlockRAM(片内):用于行缓存、查找表、小尺寸参数,延迟 1~2 个时钟周期。
- DDR(片外):用于整帧缓存、大容量历史帧,高延迟、高带宽。
是否需要帧缓存?
- 是(如图像旋转、上下翻转)→ DDR 架构 + 乒乓 Buffer
- 否(如空间滤波、色彩转换)→ 纯流式 + Line Buffer
带宽计算思维:4K@60fps 数据量约 12.4 Gbps。若 DDR 理论带宽为 25.6 GB/s,看似充足,但需考虑总线效率(约 70%)及双倍读写开销(读旧帧 + 写新帧),实际余量可能不足。这是算法设计必须考量的硬约束。
3.2.3 定点化工程方法(Fixed-Point Engineering)
定点化并非简单地将浮点数转为整数,而是涉及量化精度管理、溢出处理与误差传播控制的系统工程。
3.3 实战案例规划(由易到难,纯 PL → PS+PL)
Level 1:纯组合逻辑(Pixel-wise)
- Demosaic(去马赛克):理解 Bayer Pattern 的流式重组,需 2 行缓存实现 3×3 窗口。
- Gamma 校正:使用 BRAM 构建 256×8bit 查找表(输入 8bit,输出 8bit),纯组合逻辑查表。
- Color Matrix:3×3 矩阵乘法,9 个乘法器并行,需合理设计定点化系数。
Level 2:需要时序控制(Line-based)
- 2D 卷积/滤波:滑动窗口实现,掌握
shift_reg与valid信号的生成逻辑。 - 直方图统计:每行统计 + 帧间累加,理解部分和(Partial Sum)的存储与合并。
- 行列级处理:如黑电平校正(每行减去暗场平均值)。
Level 3:帧间处理(Frame-based,需过 DDR)
- 时域降噪:当前帧与 DDR 中的历史帧进行加权平均。
- 数字稳像:帧缓存 + 仿射变换(需双线性插值)。
Level 4:PS+PL 协同(控制流与数据流分离)
- 架构分层:
- PL(可编程逻辑):负责像素级高吞吐处理(如 Bayer2RGB、降噪、色彩空间转换)。
- PS(处理系统/软核):负责帧级决策(如根据直方图调整 AE 参数、计算 Gamma 曲线)。
- 典型案例:
- AE(自动曝光):PL 分块统计亮度直方图 → PS 分析并计算目标曝光值 → PS 写入传感器寄存器。
- AF(自动对焦):PL 计算梯度(Sobel + 平方和)→ PS 接收清晰度评价值 → PS 控制对焦电机。
4. 核心思想与课程规划
致算法工程师:
摒弃 for i=1:H, for j=1:W 的软件思维。硬件是 always @(posedge clk),每个时钟周期输出一个像素。边界处理必须显式设计(复制/镜像/常数填充),不可依赖 MATLAB 的默认 Padding。多级处理(去噪→增强→色彩转换)会累积舍入误差,需合理设置各级量化精度。
致 FPGA 工程师:
先理解算法原理,再编写 RTL。例如,理解 Sobel 核 [1 2 1] 背后的高斯平滑与差分概念,才能写出高效的硬件结构。
本课程旨在培养兼具算法调参能力与硬件实现视野的 System Architect,能够熟练在 MATLAB/C/Python 中验证算法,在 Vivado 中分析 RTL 与 Timing Report,并精准评估系统带宽与功耗。此类人才在工业相机、医疗影像、车载视觉领域极为稀缺。
课程内容规划
| 章节 | 主题 |
|---|---|
| 第 1 节 | 思维转换——从矩阵到数据流 |
| 第 2 节 | 定点化工程——扔掉浮点计算器 |
| 第 3 节 | 滑动窗口与 Line Buffer——空间滤波的硬件灵魂 |
| 第 4 节 | 纯流水架构——空间滤波实战 |
| 第 5 节 | 图像处理与查表法 |
| 第 6 节 | 统计量计算——从像素到决策 |
| 第 7 节 | 帧缓存架构——DDR 与乒乓操作 |
| 第 8 节 | PS+PL 协同架构——控制与计算分离 |
| 第 9 节 | 高级算法实战 |
| 第 10 节 | 系统集成与工程化——从 Demo 到产品 |


