You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
技 术 长 廊<br />
在 Xilinx FPGA 中<br />
加速双边滤波处理<br />
C 到 FPGA 的转换方法<br />
可加速复数滤波器的开发和优化<br />
作者: Ed Trexel<br />
Impulse Accelerated Technologies 公司<br />
高级应用工程师<br />
edward.trexel@impulsec.com<br />
Dov Stamler<br />
Vigilant Technology 公司<br />
硬件工程师<br />
dovs@vigilanttechnology.com<br />
许多视频应用都使用双边滤波的方<br />
法来对图像做平滑处理,同时保留其边<br />
缘细节信息。其中一种应用是在视频预<br />
处理过程中使用双边滤波器减少随机噪<br />
声,并在实时视频环境中提高压缩效率。<br />
Vigilant 提供智能 IP 监视和安全<br />
解决方案,目前为机场、政府机关、金<br />
融机构、教养院、娱乐场所和市中心的<br />
数万台摄像头提供支持。<br />
双边滤波器是高级闭路电视系统<br />
(CCTV) 的组成部分。本文说明使用 C<br />
到 FPGA 的转换工具将双边滤波器从<br />
原始软件模型发展到实际硬件实现的过<br />
程。我们从一个经过验证的 C 语言模型<br />
开始,通过使用 C 到硬件的转换工具和<br />
迭代设计方法,对模型进行了硬件实现。<br />
为了尽快完成原型设计和算法实验,我<br />
们使用了常用且熟悉的 C 语言工具进行<br />
调试和软硬件设计分析。<br />
赛灵思中国通讯 25 期 © 2007 Xilinx Inc. 版权所有。XILINX、Xilinx 标志以及本文件中包括的其他品牌名称,是 Xilinx, Inc. 的商标。所有其他商标都是其各自所有者的财产。
硬件级迭代测试是这一转化过程的<br />
重要组成部分。我们使用 FPGA 嵌入<br />
式软件测试激励程序完成了这一测试过<br />
程。为此目的,我们用 Xilinx® Virtex -4<br />
FX 器件的嵌入式处理器功能对图像滤<br />
波算法进行了直接的硬件在环嵌入式测<br />
试。<br />
双边滤波<br />
双边滤波器是多种重要图像算法的<br />
典型代表。其工作方式是:对每个像素,<br />
用所涉及像素周边紧邻的像素按以下公<br />
式算出一个新值:<br />
∑ f × coeff<br />
n n<br />
New pixel =<br />
∑coeff<br />
其中各系数按下式计算:<br />
新系数<br />
coeff n = ORIGCOEFF X KERNEL<br />
重新计算的像素与其周边像素一起<br />
构成一个 3 x 3 的矩阵,称为“输入<br />
矢量”。将输入矢量送至滤波器,其中<br />
各像素并行形成一个 9 字节宽的数据<br />
通路。滤波器从每个输入矢量计算出中<br />
心像素的新值,称为“输出矢量”,新<br />
值宽度为 1 字节。输出像素的计算是<br />
双边滤波器的核心,由 Vigilant 开发的<br />
一种专利内核算法定义。<br />
图 1 是输入和输出矢量的示意图。<br />
从 C 语言模型着手<br />
n<br />
Vigilant 公司用 C 语言以浮点运<br />
算的形式编写了双边噪声滤波器的原<br />
始算法。作为一级优化,我们将算法中<br />
的所有数学运算都转换成了无符号定点<br />
运算。我们使用 Impulse C 工具附带的<br />
C 语言宏完成了部分转换。<br />
作为二级优化,我们用所有滤波器<br />
I/O 的缓冲流重新组织了 C 代码,以尽<br />
量减少环数并简 化数据处理。我们用<br />
Impulse C 工具中提供的流相关接口功<br />
能定义了此 I/O。<br />
n<br />
n<br />
在某些情况下,我们用单变量取代<br />
了 C 代码中的阵列参考值,以避免数<br />
据时序依赖性并形成并行计算。C<br />
代码依赖性包括求和运算,其中采用了<br />
一种计算系数的线性求和方法和一种多<br />
层方法。在这次手动优化过程中,我们<br />
用宏保持了 C 代码相对简洁以及并可<br />
移植的特性。<br />
在为硬件实现而对代码进行优化和<br />
修改时,我们使用一种标准的 C 语言<br />
调试器(Borland C++ Builder 工具的<br />
一部分)对原始的和修改后的 C 代码<br />
进行单步调试,以验证运算和应用的<br />
整体功能。在整个开发过程中,我们用<br />
代表各种闭路电视 (CCTV) 场景的实<br />
First Pixel<br />
Input Vector<br />
1 2 3<br />
4 5 6<br />
7 8 9<br />
1 2 3<br />
4 5 6<br />
7 8 9<br />
1<br />
2<br />
3<br />
4<br />
5<br />
6<br />
7<br />
8<br />
9<br />
1 2 3<br />
4 5 6<br />
7 8 9<br />
= Pixel to be passed<br />
through unprocessed<br />
Input Vector<br />
Reg1<br />
Reg2<br />
Reg3<br />
Reg4<br />
Reg5<br />
Reg6<br />
Reg7<br />
Reg8<br />
Reg9<br />
Vector In<br />
[7:0]<br />
[7:0]<br />
[7:0]<br />
[7:0]<br />
[7:0]<br />
[7:0]<br />
[7:0]<br />
[7:0]<br />
[7:0]<br />
Row 0<br />
Row 1<br />
Row 2<br />
[23:0]<br />
Last Pixel<br />
Input Vector<br />
Bilateral Filter<br />
in_stream_row0<br />
[23:0]<br />
际视频剪辑进行了实际验证。<br />
图 2 所示为我们用 Impulse C 流<br />
接口和一个 Xilinx ML410 开发板实现<br />
和测试双边噪声滤波器的过程。<br />
在应用的软件端(本例中是用于硬<br />
件级测试的 PowerPC 405 处理器),<br />
Impulse C 的功能是开关数据流、在数<br />
据流上读写数据,以及在需要时发送状<br />
态信息或轮询结果。在使用 Virtex-4<br />
FX 器件的情况下,可将数据流的读写<br />
指定为利用辅助外设 (APU) 接口的操<br />
作,该 接 口 提供软硬件之间的高性 能<br />
串 行 连 接,能在单次事务中 传 输多达<br />
128 位数据。<br />
Output<br />
Vector<br />
5<br />
col<br />
0<br />
col<br />
2<br />
Output Pixels as read by Reader<br />
One Line (col=0 ..719)<br />
col<br />
3<br />
col<br />
4<br />
col<br />
5<br />
5 5 5 5 5 5 5 5 5<br />
= Processed<br />
in_stream_row1 bileateral_filter_proc() out_stream<br />
[23:0] [23:0]<br />
[7:0] [7:0]<br />
[23:0]<br />
in_stream_row2<br />
[23:0]<br />
图 1 - 双边滤波器处理流程<br />
图 2 - 数据流与进程框图<br />
技 术 长 廊<br />
col<br />
716<br />
col<br />
717<br />
col<br />
718<br />
RegOut<br />
col<br />
719<br />
Vector Out<br />
2007 年夏季刊
技 术 长 廊<br />
生成和测试 FPGA 硬件<br />
在生成硬件代码时,Impulse C 编<br />
译器从原本要按顺序执行的 C 语言语<br />
句中提取出可并行执行的底层级(lowlevel)成分,循环之类的结构在更高层<br />
级上执行,或者展开或者用流水线处理,<br />
以提高流量。这些编译器优化可以让开<br />
发人员节省大量时间。<br />
Impulse C 编译器用 VHDL 或<br />
Verilog 语言生成硬件代码。该硬件代<br />
码用 Xilinx ISE 软件合成。在处理器<br />
端,编译器生成准备在 PowerPC 或<br />
MicroBlaze 处理器上使用的运行库。<br />
硬件级单元迭代测试是本项目的重<br />
要组成部分。利用嵌入式 PowerPC,我<br />
们得以将处理器用作测试生成器,以全<br />
速检验滤波器。用这种方法,可以验证<br />
数据的正确性,还可以直接测定滤波器<br />
的性能和流量。<br />
事实上,鉴于涉及视频数据的测试<br />
需要快得多的硬件速度运算,利用嵌入<br />
式 PowerPC、完全以 C 语言进行测试<br />
的方法远比 HDL 仿真法更实用。此过<br />
程证明 Xilinx Platform Studio (XPS)<br />
工具的价值是不可估量的。XPS 包括<br />
一个用于 Xilinx ML410 开发板的板级<br />
支持包,允许将嵌入式 PowerPC 设置<br />
成测试生成器,令其通过 Virtex-4 FX<br />
APU 接口与硬件滤波器通讯。Impulse<br />
工具具有 XPS 软硬件导出功能,这些<br />
功能大大简化了从已生成的双边滤波器<br />
硬件创建定制 APU 连接外设的过程。<br />
ISE 工具负责初步测定尺寸和时钟<br />
速度性能,而 ML410 板则负责最终确<br />
定生成的滤波器在硬件中是否工作正常。<br />
我们在开发过程的不同阶段使用了 HDL<br />
仿真,目的是验证所生成 HDL 代码的<br />
功能,但更重要的是观察循环级运算,<br />
以找出优化 C 代码的机会。<br />
HDL 仿真对于所生成硬件的流水线<br />
密集部分来说价值有限,但在分析所生<br />
赛灵思中国通讯 25 期<br />
利用嵌入式 PowerPC,可将处理器用作测试生成器,<br />
来全速检验滤波器<br />
成 HDL 代码的顺序块和顺序级时却证<br />
明相当有效。通过使用 Impulse 交互式<br />
优化器,可以将这种 HDL 级分析直接<br />
回溯到 C 源代码,该优化器可对 C 代<br />
码的并行关系进行可视化处理,帮助把<br />
生成的硬件代码与原始 C 语言源代码<br />
的相应部分一一对应起来。<br />
FPGA 的转换工具能大大缩短将复杂算<br />
法转换成硬件代码所需的开发时间,但<br />
使用这些工具时必须慎之又慎。为了得<br />
到能与手工实现的 HDL 代码相媲美的<br />
结果, 您可能 需 要使用迭代优 化法。<br />
幸 运的是,这些 技术都在嵌入式软件<br />
开发者的经验和技能范围之内。<br />
迭代优化<br />
滤波器版本 占用的 Slice 数 帧速率<br />
开发出初步的、非优化硬 并行多进程 3,592 12.11 Hz<br />
件原型后,我们开始了迭代 流水线多进程 1,570 10.10 Hz<br />
优 化过程,以满足系统的时<br />
序和尺寸限制。 根 据 相似滤<br />
流水线单进程 930 65.31 Hz<br />
波器的手动优化 HDL 实现<br />
的前期经验、可 用 资源和实<br />
时视频要求 , Vigilant<br />
表 1 - 逐步改进的迭代 C 语言优化结果<br />
制订出 1,000 个 FPGA Slice 的预算, 结论<br />
其目标视频数据速率为每秒 60 帧。<br />
实现软件到硬件转换的设计工具可<br />
我们初步修改了算法结 构,将关 以在复杂 FPGA 算法的快速原型设计与<br />
键 环 放置在 两 个并行的独立进程中。 开发中发挥重要作用。不过,要获得可<br />
这种优 化方法最初显得十分有价 值, 与手工实现的 HDL 代码相媲美的性能,<br />
具有相对较高的 143 MHz 时钟频率, 就需要一定层次的手工优化。迭代式设<br />
但它却受到了一条不连贯流水线的 限 计工具与交互式设计及优化工具相结合<br />
制 。这一特征致使系统性 能 受限于最 是解决大型嵌入式高性能计算应用的复<br />
慢流水线进程的延迟。 即 使 让两个进 杂性的有效办法。<br />
程在一个系统级流水线中并行运行, 有关 C 到 FPGA 编程与优化的进<br />
最 高 速 率 仍然要 比 所要求 的像素速 率 一步信息,请访问 www.ImpulseC.com/<br />
低得多。<br />
xilinx。<br />
进一步分析后,我们对 C 代码做<br />
了种种修改,包括为主 滤波环另 行使<br />
用一个流水线进程。经过这一系列优化,<br />
滤波器满足了预算的 Slice 数,在使用<br />
仅 27 MHz 的 FPGA 时钟速率(这是<br />
以 BT.601 格式接收 D1 视频流时的输<br />
入时钟速率)时就达到了稍稍多于 15<br />
ms 的单帧速率(每秒 66 帧)。表 1<br />
概述了这些结果。<br />
本实例中相差悬殊的性能比较结果<br />
强调了使用合适的、面向 FPGA 的 C<br />
语言编程方法的重要性。尽管 C 到