阶段5:实战项目

第28课:去噪处理器

空时联合降噪引擎:时域递归滤波+空域双边滤波

去噪处理器原理

空时联合降噪结合时域递归和空域双边滤波。双边滤波权重同时考虑空间距离和值域差异,实现保边降噪。硬件简化:用量化LUT替代exp运算。时域递归保留细节但有运动拖影,运动自适应alpha可解决:静止alpha小(强降噪),运动alpha大(保运动)。

Verilog实现

// 第28课:去噪处理器 - 空时联合
module denoise_processor #(parameter DATA_W=8, IMG_W=640, IMG_H=480)(
    input  wire                clk, rst_n,
    input  wire                valid_in,
    input  wire [DATA_W-1:0]   data_in,
    input  wire                sof_in, eol_in,
    input  wire [7:0]          sigma_r, sigma_s, t_alpha,
    input  wire                enable,
    output reg                 valid_out,
    output reg  [DATA_W-1:0]   data_out
);
    reg [DATA_W-1:0] fb[0:IMG_W*IMG_H-1]; reg [19:0] addr;
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) addr<=0; else if (sof_in) addr<=0; else if (valid_in) addr<=addr+1;
    end
    reg [DATA_W-1:0] pp; reg signed [17:0] tm;
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin pp<=0;tm<=0; end
        else if (valid_in) begin pp<=fb[addr]; tm<=$signed({1'b0,data_in})*$signed({1'b0,t_alpha})+$signed({1'b0,fb[addr]})*$signed({1'b0,8'hFF-t_alpha}); end
    end
    reg [DATA_W-1:0] to;
    always @(*) begin if(tm[17]) to=0; else if(|tm[17:15]) to=8'hFF; else to=tm[14:7]; end
    reg [DATA_W-1:0] lb0[0:IMG_W-1],lb1[0:IMG_W-1]; reg [11:0] col;
    reg [DATA_W-1:0] w00,w01,w02,w10,w11,w12,w20,w21,w22;
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin col<=0;{w00,w01,w02,w10,w11,w12,w20,w21,w22}<='0; end
        else if (valid_in) begin
            col<=(sof_in||col==IMG_W-1)?0:col+1;
            lb1[col]<=lb0[col]; lb0[col]<=to;
            w00<=w01;w01<=w02;w02<=lb1[col]; w10<=w11;w11<=w12;w12<=lb0[col];
            w20<=w21;w21<=w22;w22<=to;
        end
    end
    // Simplified bilateral: use averaging with weight based on difference
    reg [11:0] dv0,dv1,dv2,dv3,dv4,dv5,dv6,dv7;
    always @(*) begin
        dv0=(w00>w11)?(w00-w11):(w11-w00); dv1=(w01>w11)?(w01-w11):(w11-w01);
        dv2=(w02>w11)?(w02-w11):(w11-w02); dv3=(w10>w11)?(w10-w11):(w11-w10);
        dv4=(w12>w11)?(w12-w11):(w11-w12); dv5=(w20>w11)?(w20-w11):(w11-w20);
        dv6=(w21>w11)?(w21-w11):(w11-w21); dv7=(w22>w11)?(w22-w11):(w11-w22);
    end
    function automatic [7:0] bw; input [11:0] d; input [7:0] s;
        begin if(d<({4'b0,s})) bw=8'hFF; else if(d<({4'b0,s,1'b0})) bw=8'hC0; else if(d<({3'b0,s,2'b0})) bw=8'h80; else bw=8'h00; end
    endfunction
    reg [7:0] w0,w1,w2,w3,w4,w5,w6,w7;
    always @(*) begin w0=bw(dv0,sigma_r);w1=bw(dv1,sigma_r);w2=bw(dv2,sigma_r);w3=bw(dv3,sigma_r);
        w4=bw(dv4,sigma_r);w5=bw(dv5,sigma_r);w6=bw(dv6,sigma_r);w7=bw(dv7,sigma_r); end
    reg [19:0] ws,vs;
    always @(*) begin ws=8'hFF+w0+w1+w2+w3+w4+w5+w6+w7;
        vs=w11*8'hFF+w00*w0+w01*w1+w02*w2+w10*w3+w12*w4+w20*w5+w21*w6+w22*w7; end
    reg [DATA_W-1:0] bo;
    always @(*) bo=(ws>0)?(vs/ws):w11;
    always @(posedge clk) begin if(valid_in&&enable) fb[addr]<=bo; end
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin valid_out<=0;data_out<=0; end else begin valid_out<=valid_in; data_out<=enable?bo:data_in; end
    end
endmodule

Verilator验证通过 — 本课Verilog代码已通过 Verilator --lint-only 检查。

仿真验证

练习

  1. 扩展模块功能
  2. 优化资源使用
  3. 仿真验证关键场景

成就解锁

深入理解:去噪处理器进阶

本节深入探讨去噪处理器在FPGA实现中的关键设计决策和优化策略。

时序与流水线设计

视频处理模块的时序设计需要考虑以下因素:

资源优化策略

FPGA资源有限,视频处理模块需要精心优化:

策略适用场景节省资源
时分复用乘法器像素时钟远低于系统时钟DSP 4~8x
移位替代乘法系数为2的幂次DSP 1个/次
CSD编码固定系数乘法DSP全部
查表替代计算非线性函数(sin,exp)逻辑大量
对称性利用FIR系数对称乘法器减半

定点精度分析

视频处理中定点运算的精度直接影响图像质量。分析方法:

  1. 最坏情况分析:追踪每个运算级的最大误差累积
  2. 统计方法:假设误差均匀分布,计算标准差
  3. 蒙特卡洛仿真:大量随机输入统计输出PSNR

8bit视频处理的经验法则:中间结果至少保留12bit,最终输出截断到8bit。

可配置参数设计

好的视频处理模块应该是参数化的:

验证策略

视频模块的完整验证包括:

与前后模块的接口

标准视频模块接口信号:

input  wire                clk, rst_n,     // 时钟复位
input  wire                valid_in,        // 输入有效
input  wire [DATA_W-1:0]   data_in,         // 输入数据
input  wire                sof_in, eol_in,  // 帧起始/行结束
output reg                 valid_out,       // 输出有效
output reg  [DATA_W-1:0]   data_out,        // 输出数据
output reg                 sof_out, eol_out // 帧起始/行结束

这种接口设计使模块可以自由级联,形成处理流水线。

功耗考虑

视频处理是持续运行的,功耗优化很重要:

进阶主题与优化

双边滤波的快速算法:暴力双边滤波复杂度O(N^2)。快速方法包括:1)降维双边滤波(先1D水平再1D垂直,近似但快) 2)网格空间双边滤波(将5D空间量化到3D网格) 3)递归双边滤波(用IIR滤波近似)。FPGA常用降维法,复杂度O(2N)。

时序优化

当像素时钟较高(如148.5MHz for 1080p)时,关键路径可能无法满足时序约束。优化方法:

面积优化

当FPGA资源紧张时,可以牺牲吞吐率换取面积:

功耗优化

视频处理模块持续运行,功耗优化很重要:

调试技巧

附录

关键术语表

术语英文说明
像素Pixel图像最小单元
Frame一帧完整图像
Field隔行扫描的半帧
消隐Blanking非有效视频区域
流水线Pipeline多级并行处理架构
定点数Fixed-point有限精度数值表示
饱和截断Saturation超出范围钳位到边界
行缓冲Line Buffer缓存一行像素的存储器
帧缓冲Frame Buffer缓存一帧图像的存储器
时序Timing视频同步信号参数

本课核心知识点

  1. 算法原理:理解去噪处理器的数学基础和物理意义
  2. 定点化:从浮点公式到Q格式定点实现
  3. 流水线设计:多级流水线平衡时序和面积
  4. Verilog实现:参数化、可配置、可验证的RTL代码
  5. 仿真验证:测试向量设计、边界条件覆盖

同阶段相关课程

前置知识

推荐阅读

Verilog编码检查清单

常见错误与调试

错误现象可能原因解决方法
输出全零复位未释放或valid未传播检查rst_n和valid链
色彩偏移系数位宽不足或溢出增加中间结果位宽
行间错位行缓冲地址不对齐检查写地址和读地址
画面闪烁时序违例或跨时钟域添加同步器或约束
边缘伪影边界处理不正确添加边界检测和钳位

本课资源估算

资源估计使用量说明
LUT100~500加法器、比较器、选择器
FF50~200流水线寄存器、状态机
DSP0~9乘法器(色彩转换9个)
BRAM(18K)0~6行缓冲(2~4行)、帧缓冲、LUT
延迟2~5 cycles流水线级数

Verilator验证命令

# 语法检查
verilator --lint-only verilog/lesson_28.v

# 带波形仿真(需要testbench)
verilator --trace --cc verilog/lesson_28.v --exe tb.cpp
make -C obj_dir -f Vlesson_28.mk
./obj_dir/Vlesson_28