2026年FPGA大赛用国产高云FPGA做实时视频去雾,暗通道先验算法模块LUT和BRAM不够用,怎么通过行缓存和流水线重构硬挤进去?求具体架构设计

开放3 回答 37 浏览

我们队伍选了高云FPGA做实时视频去雾,用的暗通道先验算法,结果综合下来LUT和BRAM直接爆了。导师说要用行缓存替代整帧缓存,再配合流水线重构,但具体怎么拆分模块、每级流水怎么分配资源,完全没有头绪。有没有做过类似项目的大佬分享一下具体的架构设计思路?比如导向滤波那部分怎么用滑动窗口实现,资源占用大概能降多少?

分享:

3 个回答

  • 电路板玩家

    先别急着上导向滤波,你现在的瓶颈大概率不在去雾本身,而在数据通路的组织方式上。暗通道求取那一步,用3×3滑窗加行缓存是标准做法:行缓存只需要三行RGB数据,每来一个新像素,窗口内九个点的最小值用比较器树算,一个时钟出结果,根本不需要整帧BRAM。透射率细化那部分,如果你用的是导向滤波,建议拆成两次均值滤波来做:第一次对暗通道图做均值,第二次对引导图与暗通道的乘积做均值,最后用一次除法求系数。均值滤波本身也可以用行缓存实现,窗口大小固定的话,行缓存深度就是图像宽度,宽度按你的分辨率算,一般1080p也就1920个像素,一个像素按8bit算,三行缓存不到6KB,比整帧缓存省一个数量级。双边滤波替代导向滤波也是个路子,但要注意双边滤波的权重计算会引入乘法和指数运算,LUT可能反而涨,建议先综合一次看看资源报告再决定。另外,你提到LUT爆了,常见原因是暗通道求取时用了太多组合逻辑做比较,试试把3×3窗口九个值拆成三级比较树,每级只比较三个数,这样时序和LUT都会好很多。数据通路按行流水的话,每行只保留当前窗口需要的三行数据,行与行之间用FIFO衔接,这样整个模块的BRAM占用就是行缓存加几个小FIFO,基本可控。最后给你个参考,之前有人用类似架构在国产FPGA上做到1080p30帧,BRAM占用大概在总资源的15%以内,LUT占用看窗口大小,一般能压到30%以下。你们现在综合爆了,先查一下是不是暗通道那步用了整帧存储,或者导向滤波用了全图递归实现,这两处是最常见的资源杀手。你们用的高云具体是哪款型号?不同系列的LUT和BRAM比例差别挺大的,这会影响方案选择。

  • 变量名

    你这个问题其实是个典型的「先有算法后有硬件」的坑,暗通道先验本来是给PC端设计的,直接往FPGA上搬必然爆资源。我建议你先做一次资源预算:把算法拆成暗通道求取、透射率估计、细化、恢复四个模块,每个模块单独综合,看各自的LUT和BRAM占用,这样能定位到底是谁吃掉了资源。大概率是暗通道求取用了全局最小值缓存,或者细化部分用了全图导向滤波。行缓存替代整帧缓存的核心思路是「数据只保留当前计算窗口所需」,但你要注意行缓存不是万能的,它适合窗口小的操作,如果窗口超过7×7,行缓存深度会直线上升,这时候要考虑分块处理或者降分辨率。导向滤波用均值滤波分步实现,本质上是把全局优化问题退化成了局部均值问题,虽然效果会略差一点,但在FPGA上这是性价比最高的做法。透射率细化用双边滤波替代导向滤波,可以减少除法器和乘法器资源,但双边滤波的权重计算需要查表或者用CORDIC,LUT不一定省,建议你先实现一个简化版,权重用固定系数或者查一个小ROM,这样资源可控。数据通路按行流水,你要注意时序收敛问题:每级流水之间要插入寄存器打拍,避免组合逻辑路径过长。另外,你们导师说的「硬挤进去」,其实还有一招是复用计算单元:暗通道求取和均值滤波都用同一个比较器阵列,通过状态机分时复用,这样LUT能省一半,但控制逻辑会复杂一些,适合你们队伍里有人熟悉FSM设计的情况。最后给你一个排查顺序:先查综合报告里BRAM的使用情况,看看是不是有隐形的整帧缓存;再查LUT是不是消耗在除法器或者指数运算上,如果是,换成移位加查表;最后查时序报告,看看是不是因为路径太长导致综合器为了满足时序而复制逻辑,这也是LUT暴涨的常见原因。资源占用能降多少不好说,但按我的经验,从爆资源到能放下,通常需要迭代两三轮,每轮降30%到50%是可能的。你们现在用的是高云的哪款芯片,具体资源量是多少?这决定了你能用多少行缓存和多大的窗口,如果是小容量型号,可能还要考虑把去雾分辨率降到720p。

  • FPGA小学生

    说实话,你们这个情况我第一反应不是资源不够,而是算法映射的粒度选错了。暗通道先验在PC上跑,大家都是直接调库,但上FPGA你得把每个算子当成一个独立的小状态机来想。你导师说的行缓存替代整帧缓存,方向是对的,但有个坑:高云这系列器件的BRAM容量和分布跟Xilinx不太一样,你要是照搬网上那些基于Vivado的例子,综合出来资源报告肯定对不上。我的建议是第一步先别急着优化算法,先把你的暗通道求取模块单独拎出来,用3×3滑窗加三级行缓存,每行缓存存的是当前行的灰度值,窗口内九个像素用比较器树求最小值,这样BRAM占用基本就是三行乘图像宽度乘位宽,1080p的话大概不到6KB,比你存整帧省了将近一个数量级。第二步才是导向滤波,你把它拆成两次均值滤波加一次除法,均值滤波继续复用行缓存,窗口可以设大一点比如7×7,但要注意行缓存深度会跟着窗口半径涨,7×7就要7行缓存,资源翻倍还多,所以如果还是紧,就考虑把去雾分辨率降到720p试试。最后透射率细化那块,双边滤波确实能省LUT,但代价是处理延迟会变大,因为双边滤波要算空间距离和灰度差两个权重,组合逻辑路径会长不少,你得在时序上留余量。我建议你先按这个顺序改一版,综合完看资源报告再回来调。话说你们目标帧率是多少?60帧和30帧对流水线深度的要求差挺多的。

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

提问者

数字电路新手查看主页
浏览「其他」

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

相关问题

同分类

提问建议

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