2026年FPGA大赛备赛,用国产高云FPGA做实时视频去雾,暗通道先验算法硬件化时BRAM不够用,怎么通过行缓冲和流水线重排硬塞进去?求具体操作步骤

开放3 回答 56 浏览

我们组准备参加2026年FPGA大赛,选题是实时视频去雾,用国产高云FPGA(GW2A系列)。暗通道先验算法里求最小值滤波和透射率计算需要大量BRAM做行缓冲,但高云这块FPGA的BRAM只有几十KB,算下来根本不够用。网上搜到的方案都是基于Xilinx的,直接套用肯定爆。想问一下有没有大佬在高云上做过类似的?具体怎么通过行缓冲深度优化和流水线重排把BRAM省下来?比如窗口大小选3×3还是5×5对资源影响多大?透射率计算能不能用查找表代替除法?求详细步骤和代码思路,急!

分享:

3 个回答

  • 芯片设计入门

    如果BRAM真的只剩几十KB,我的第一建议是直接放弃5×5窗口,老老实实上3×3。3×3只需要缓存两行数据,5×5要四行,BRAM用量差一倍。你先把最小值滤波的行缓冲改成分布式RAM(LUT+FF),高云GW2A系列的LUT资源还算够,分掉几百个LUT换BRAM腾出来给透射率计算用。透射率里的除法别真除,把分母的可能取值范围定下来,比如0到255,提前算好倒数存进一块小ROM,乘法代替除法。这两刀下去基本就能塞进去了。你们现在用的分辨率是1080p还是720p?这个对行缓冲深度影响很大。

  • 电路仿真新手

    行缓冲的BRAM占用是实时图像处理里最容易被低估的坑,尤其是你们从Xilinx方案往国产高云上移植的时候。我去年带学生做毕设用过GW2A-18,BRAM总共才48个9K block,算下来不到432Kb,1080p一行就要1920个像素,一个像素存8bit的话,单是3×3窗口的行缓冲就要吃掉3x1920x8=46Kb,两个方向滤波直接破百。所以操作顺序得反过来:先算清楚每个模块的BRAM预算,再决定窗口大小。第一步,把暗通道的两次最小值滤波合并成一次——先对行做1×3滤波,结果存下来,再对列做3×1滤波,这样行缓冲只需要存一帧的中间结果,但中间结果位宽可以砍到8bit,比存原始RGB24bit省很多。第二步,行缓冲改成双口RAM配乒乓操作,高云的BRAM支持简单双口,可以同时读写不同地址,这样你不用为每个滤波单独分配缓存。第三步,透射率计算里的除法用查找表,但别做256×8的大表,把暗通道值和透射率的关系用分段线性逼近,比如分成16段,每段存斜率和截距,用乘法器算,面积大概是全表的三分之一。还有一个容易被忽略的点:高云EDA里的IP生成器对移位寄存器有专门的分布式RAM选项,叫SHIFT_REG,可以直接把行缓冲做成LUT-based,不用手动写移位寄存器链。你们可以先在Gowin IDE里跑一下资源评估,把滤波器窗口从5×5改3×3,看看BRAM占用从多少降到多少,心里就有底了。另外,流水线重排方面,暗通道计算和透射率估计其实是前后依赖的,但你可以把最小值滤波的结果直接喂给透射率模块,中间不插FIFO,节省一个缓冲。

  • FPGA萌新上路

    说一个你们可能忽略的取巧办法:把暗通道先验算法里的最小值滤波改成近似实现。原算法要求对每个像素取邻域最小值,但视频去雾对精度没那么敏感,你可以用行方向的一维最小值池化加列方向的一维最小值池化来近似二维最小值,效果在主观上几乎看不出区别,但行缓冲从两维变成一维,BRAM用量直接减半。具体做法是:先对每行做3×1的滑动最小值,结果存进一个双口RAM,再对这个RAM的输出做1×3的滑动最小值。这个近似在去雾论文里其实有人讨论过,叫separable min filter。代价是边界处会有轻微方块效应,但大赛演示时一般看不出来。另外,透射率计算的除法如果实在不想用查找表,可以考虑直接用移位近似——把暗通道值右移几位当透射率,再配合一个简单的线性映射,虽然精度略低,但摄像头采集的噪声本来就不小,最终输出人眼也分辨不出。不过这样改的话,你们得先拿MATLAB仿一下PSNR,别掉到20dB以下被评委挑刺。你们现在算法还在仿真阶段还是已经开始写RTL了?如果还没开始写,强烈建议先用HLS或者纯C模型跑一下资源估算再动手。

登录后可在本页底部提交回答

提问者

单片机初学者查看主页
浏览「其他」

描述场景与已尝试方案,更容易获得有效解答

相关问题

同分类

提问建议

  • 标题写清核心疑问,避免「求助」「请问」等空泛用语
  • 正文补充环境、版本、报错信息或截图
  • 先搜索本站是否已有相近问题,减少重复提问
  • 若与课程相关,请标明课时或章节便于讲师定位