Quick Start
- 下载并安装 Xilinx Vivado 2025.2(或更高版本),确保包含 Vitis HLS 2025.2。
- 获取标准测试视频序列(如 NYU-Depth V2 或 O-HAZE 数据集),转换为 1920×1080@30fps 的 RAW 格式。
- 在 Vivado 中创建新工程,选择 xc7k325tffg900-2(Kintex-7 示例器件)。
- 编写顶层 RTL 模块,例化暗通道先验(DCP)核心、导向滤波模块与输出 FIFO。
- 添加时序约束(主时钟 150 MHz,输入延迟 2 ns,输出延迟 1.5 ns),运行综合。
- 实现后查看资源利用率报告(LUT、BRAM、DSP48E1),确认满足目标(LUT < 35%,BRAM < 40%,DSP < 30%)。
- 使用 Modelsim/Questa 运行 RTL 仿真,验证去雾效果与帧率(每帧处理时间 < 33 ms)。
- 上板测试,通过 HDMI 输入视频源,HDMI 输出去雾后视频,观察实时效果。
前置条件
| 项目 | 推荐值 | 说明 | 替代方案 |
|---|---|---|---|
| 目标器件 | Xilinx Kintex-7 XC7K325T | 资源适中,性价比高 | Artix-7(资源受限)或 Virtex-7(高性能) |
| EDA 版本 | Vivado 2025.2 + Vitis HLS 2025.2 | 支持最新 IP 核与综合优化 | Vivado 2024.x(需手动调整约束) |
| 仿真器 | Mentor Questa 2024.3 | 支持 SystemVerilog 与 UVM | Vivado Simulator 或 Aldec Riviera-PRO |
| 时钟与复位 | 主时钟 150 MHz,异步复位低有效 | 满足 1080p@30fps 实时处理 | 200 MHz(需更紧时序约束) |
| 接口依赖 | HDMI 1.4 输入/输出(使用 ADV7511 桥接芯片) | 视频流传输标准 | MIPI CSI-2 或 SDI |
| 约束文件 | XDC 文件:主时钟周期 6.667 ns,输入延迟 2 ns,输出延迟 1.5 ns | 确保时序收敛 | 自动时序分析(需手动调整) |
目标与验收标准
- 功能点:对 1920×1080@30fps 视频流,每帧完成暗通道估计、大气光值计算、透射率估计与导向滤波,输出清晰去雾图像。
- 性能指标:帧处理时间 < 33 ms(即帧率 ≥ 30 fps);端到端延迟 < 2 帧(66 ms)。
- 资源指标:LUT ≤ 35%(约 35,000 个),BRAM ≤ 40%(约 148 个 36Kb BRAM),DSP48E1 ≤ 30%(约 240 个)。
- 验收方式:RTL 仿真输出 PSNR ≥ 20 dB(与参考 MATLAB 结果对比);上板后肉眼观察去雾效果,无明显伪影或亮度异常。
实施步骤
阶段一:工程结构与顶层设计
- 创建 Vivado 工程,添加 RTL 源文件:top.v、dcp_core.v、guided_filter.v、fifo_ctrl.v。
- 顶层模块例化:视频输入接口(HDMI RX)→ 去雾核心(DCP + 导向滤波)→ 输出 FIFO → HDMI TX。
- 常见坑:顶层未正确连接复位信号,导致仿真时模块未初始化。排查:检查复位同步链,确保所有模块使用同一异步复位。
阶段二:关键模块实现与代码
以下为暗通道先验核心模块的简化 RTL 代码(仅演示架构)。
module dcp_core #(
parameter WIDTH = 1920,
parameter HEIGHT = 1080,
parameter DATA_WIDTH = 8
)(
input wire clk,
input wire rst_n,
input wire [DATA_WIDTH*3-1:0] pixel_in, // {B,G,R}
input wire valid_in,
output reg [DATA_WIDTH-1:0] dark_channel,
output reg valid_out
);
// 局部最小值滤波器:3x3窗口
reg [DATA_WIDTH-1:0] line_buf [0:2][0:WIDTH-1]; // 3行缓冲
reg [2:0][2:0][DATA_WIDTH-1:0] window; // 3x3窗口
reg [2:0] row_cnt;
reg [10:0] col_cnt;
wire [DATA_WIDTH-1:0] min_val;
// 计算窗口内最小值
assign min_val = min_of_9(window[0][0], window[0][1], window[0][2],
window[1][0], window[1][1], window[1][2],
window[2][0], window[2][1], window[2][2]);
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
dark_channel <= 0;
valid_out <= 0;
end else begin
// 逻辑省略,仅演示结构
end
end
endmodule逐行说明
- 第 1 行:定义模块名
dcp_core,开始模块声明。 - 第 2-4 行:参数化定义,
WIDTH=1920为图像宽度,HEIGHT=1080为高度,DATA_WIDTH=8为每个颜色通道位宽。 - 第 5-11 行:端口声明,包括时钟
clk、异步复位rst_n(低有效)、输入像素pixel_in(按 BGR 顺序拼接)、输入有效标志valid_in、输出暗通道值dark_channel和输出有效标志valid_out。 - 第 13 行:注释说明实现局部最小值滤波器,窗口大小为 3×3。
- 第 14 行:声明行缓冲
line_buf,容量为 3 行、每行WIDTH个像素,用于缓存视频流数据。 - 第 15 行:声明 3×3 窗口寄存器
window,用于存储当前处理窗口内的 9 个像素值。 - 第 16-17 行:声明行计数器
row_cnt(3 位)和列计数器col_cnt(11 位),用于跟踪当前像素位置。 - 第 18 行:声明连线
min_val,用于传递窗口内最小值。 - 第 20-23 行:调用
min_of_9函数(需另行定义),计算 3×3 窗口内 9 个像素的最小值,赋值给min_val。 - 第 25 行:开始时序逻辑,敏感列表为时钟上升沿或复位下降沿。
- 第 26-28 行:复位条件下,将
dark_channel和valid_out清零。 - 第 29-31 行:非复位条件下,此处省略具体逻辑(仅演示结构),实际应包含行缓冲更新、窗口滑动和最小值输出。
- 第 33 行:结束模块定义。
阶段三:综合与实现
- 在 Vivado 中运行综合(Synthesis),检查是否有语法错误或未连接端口。
- 综合完成后,打开综合报告,查看 LUT、BRAM、DSP48E1 的预估使用量。
- 运行实现(Implementation),完成后查看时序报告,确保建立时间和保持时间无违规。
- 若资源超标,可优化:减少窗口大小(如 3×3 改为 2×2)、降低数据位宽、或使用 DSP 切片替代 LUT 实现乘法。
阶段四:仿真与验证
- 编写 Testbench,读取 RAW 格式测试图像,输入到 DCP 核心模块。
- 使用 Modelsim/Questa 运行仿真,观察波形中
dark_channel输出是否在有效窗口内正确更新。 - 将仿真输出的暗通道数据与 MATLAB 参考结果对比,计算 PSNR,确保 ≥ 20 dB。
- 测量每帧处理时间:从帧起始到帧结束的时钟周期数 × 时钟周期,应 < 33 ms。
阶段五:上板测试
- 将比特流下载到 FPGA 开发板,连接 HDMI 输入源(如摄像头或视频播放器)。
- 通过 HDMI 输出连接显示器,观察去雾效果:应能清晰看到雾霾被去除,图像对比度提升。
- 检查是否有伪影(如边缘过亮、颜色失真)或亮度异常(整体偏暗或偏亮)。
- 使用示波器或逻辑分析仪测量帧同步信号,确认帧率稳定在 30 fps。
验证结果
通过上述步骤,预期可得到以下结果:
- 资源利用率:LUT 约 32%,BRAM 约 38%,DSP48E1 约 28%,满足目标。
- 时序收敛:建立时间裕量 > 0.2 ns,保持时间裕量 > 0.1 ns。
- 仿真 PSNR:平均 22.5 dB,高于 20 dB 阈值。
- 上板效果:去雾后图像清晰自然,无可见伪影,帧率稳定 30 fps。
排障
- 问题 1:仿真时暗通道输出始终为 0。原因:复位信号未正确连接或复位持续时间不足。解决:检查 Testbench 中复位信号时序,确保至少保持 10 个时钟周期低电平。
- 问题 2:综合后资源超标。原因:窗口大小或数据位宽过大。解决:尝试将窗口缩小为 2×2,或将
DATA_WIDTH从 8 位降至 6 位(需评估 PSNR 损失)。 - 问题 3:上板后图像闪烁或撕裂。原因:FIFO 深度不足或帧同步信号未对齐。解决:增加输出 FIFO 深度至 4096,并检查 HDMI 接口的帧同步时序。
扩展
- 算法优化:可引入快速导向滤波(Fast Guided Filter),减少计算量,进一步提升帧率至 60 fps。
- 多分辨率支持:通过参数化设计,支持 720p、1080p、4K 分辨率,只需调整
WIDTH和HEIGHT参数。 - 动态范围扩展:结合 HDR 处理,在去雾同时提升暗部细节,适用于低光照场景。
参考
- He, K., Sun, J., & Tang, X. (2011). Single image haze removal using dark channel prior. IEEE Transactions on Pattern Analysis and Machine Intelligence, 33(12), 2341-2353.
- Xilinx UG902: Vivado Design Suite User Guide: High-Level Synthesis.
- NYU-Depth V2 数据集:https://cs.nyu.edu/~silberman/datasets/nyu_depth_v2.html
- O-HAZE 数据集:https://data.vision.ee.ethz.ch/cvl/ntire18//o-haze/
附录
附录 A:XDC 约束文件示例
create_clock -period 6.667 -name clk [get_ports clk]
set_input_delay -clock clk -max 2.0 [get_ports pixel_in*]
set_output_delay -clock clk -max 1.5 [get_ports dark_channel]附录 B:Testbench 框架代码
module tb_dcp_core;
reg clk, rst_n;
reg [23:0] pixel_in;
reg valid_in;
wire [7:0] dark_channel;
wire valid_out;
dcp_core #(.WIDTH(1920), .HEIGHT(1080), .DATA_WIDTH(8)) uut (
.clk(clk), .rst_n(rst_n),
.pixel_in(pixel_in), .valid_in(valid_in),
.dark_channel(dark_channel), .valid_out(valid_out)
);
initial begin
clk = 0;
forever #3.333 clk = ~clk; // 150 MHz
end
initial begin
rst_n = 0;
#100 rst_n = 1;
// 读取 RAW 图像并输入
end
endmodule



