正在备赛2026年FPGA大赛,选了国产高云FPGA做实时视频去雾,暗通道先验算法在PL侧BRAM不够用,算透射率时缓存窗口数据就把BRAM快吃满了。有没有具体优化方案?比如用行缓冲替代全帧缓存?或者分块处理?求大佬给个实际可行的资源压缩思路,最好能贴代码片段参考。
2026年FPGA大赛用国产高云FPGA做实时视频去雾,暗通道先验算法在PL侧BRAM不够怎么办?求具体优化方案
提问
回答 3

暗通道先验的透射率计算确实吃BRAM,核心矛盾是窗口缓存的数据量——比如15×15窗口,全帧存下来BRAM直接爆炸。你提到的行缓冲是对的,但只做行缓冲还不够,因为行缓冲本质是串行移入,而透射率需要窗口内每个像素的RGB最小值,如果每来一个像素就全窗口扫描一遍,时序和资源反而更差。实际比赛里常见做法是:把透射率计算分解成两步流水线。第一步,对每一行做滑动窗口最小值缓存,用移位寄存器加比较器树,只存当前行窗口内的RGB最小值结果,而不是存整行像素。这样每行只需要一个很浅的FIFO或寄存器组,BRAM只用来缓存跨行的中间结果,比如15行窗口就只存15个最小值,而不是15行像素。第二步,透射率取这些跨行最小值的再最小值,用一个简单的流水线比较树,资源几乎可以忽略。这样BRAM占用能压到原来1/10以下。但有个坑:高云的BRAM有最小容量限制,比如一个块最小不能低于某个深度,用行缓冲时如果每个缓存深度太浅,反而会浪费块数。所以建议先算一下你实际需要的跨行缓存深度,比如1280宽的图像,每行只存一个最小值,那15行也就15个数据,完全可以用寄存器或分布式RAM实现,根本不用BRAM。只有图像尺寸特别大或者需要存整行数据时才考虑BRAM。代码片段的话,核心就是两个模块:一个模块做行内窗口最小值计算,用流水线比较器,每个时钟出一个结果;另一个模块做帧内窗口最小值计算,用一个深度为窗口行数的FIFO或寄存器组,存每行传来的最小值,再比较输出。注意FIFO要用高云IP核里的简单双口RAM或寄存器实现,不要用BRAM模式。另外,透射率计算完后还需要导向滤波,那个才是BRAM大头,建议用行缓存+双线性插值的简化方案代替全帧导向滤波,资源会好看很多。你目前用的是高云的哪个具体型号?有些小封装的BRAM总量才几十K,必须得这么拆才够用。

行缓冲+流水线比较树,别存整帧,存每行窗口的最小值就行。BRAM只用来存跨行中间结果,大部分用寄存器或分布式RAM。高云的BRAM块数少但寄存器多,多用逻辑。

分块处理其实不如行缓冲加流水线来得直接。分块会引入块边界重叠和块间同步问题,在实时视频流里处理起来很麻烦,调试周期长。建议你先算一下暗通道窗口大小,比如15×15,那每行需要缓存15个像素的RGB最小值结果,而不是15行像素。用寄存器组把每一行的窗口最小值存下来,15行就是15个寄存器,然后每来一个新行,就更新这15个寄存器中的对应位置,同时做一次比较输出透射率。这样BRAM只用来缓存像素数据本身,比如RGB输入先写进一个深度为窗口行数、宽度为像素位宽的FIFO,供后续导向滤波或其他模块使用。暗通道计算本身可以完全不用BRAM,用移位寄存器加比较器树就能搞定。另外,高云的LUT资源相对丰富,可以拿LUT配成分布式RAM来替代小深度的BRAM,这样BRAM块就能留给必须用它的部分,比如帧缓存或大FIFO。如果你现在BRAM已经快吃满了,大概率是暗通道计算里用了全帧缓存或者每行都存了整行像素,把那个改掉,资源立马松下来。
发表回答
登录后可在本页底部提交回答
