2026年FPGA校招,面试官问手撕Verilog实现AXI4-Stream实时视频去雾,导向滤波的均值窗口怎么用行缓冲实现最省BRAM?

开放12 回答 80 浏览

面试官让我手撕Verilog实现一个实时视频去雾模块,用导向滤波算透射率,但均值滤波窗口很大,比如31×31,行缓冲深度怎么算?用移位寄存器还是BRAM实现能省资源?还有均值滤波的累加器位宽怎么确定才不会溢出?求具体推导和代码框架,最好能适配1080P60帧的时序要求。

分享:

12 个回答

  • 逻辑设计新手

    31×31的均值滤波,行缓冲深度就是30行,每行1920像素,数据位宽按输入位宽算。BRAM比移位寄存器省面积,因为大窗口下移位寄存器会吃掉大量LUT和FF,而BRAM是专用存储块。累加器位宽按窗口像素数乘数据位宽再加log2(961)就够,1080P60用BRAM双端口读一写一完全来得及。

  • 单片机入门

    面试官问这个八成是想看你有没有实际做过视频处理,而不是光背书。31×31的行缓冲,用Xilinx的XPM_FIFO或者直接例化BRAM做行延时,深度取图像宽度就行,但注意HDMI一般有消隐区,实际有效数据是1920,但你得留点余量。累加器溢出的问题,我个人建议分三步:先算每行累加和,再纵向累加,最后归一化。位宽上,输入假设8bit,窗口961个点,最大值就是8bit961,大概18bit左右,再加几bit防止中间结果溢出,取21bit比较稳。代码框架上,写一个行缓冲模块加一个滑动窗求和模块,别把所有逻辑塞到一个always块里,否则时序很难收敛。你目前是准备用Zynq还是纯FPGA方案?

  • FPGA学员2

    这题其实拆开来看就两个核心:行缓冲怎么存,累加器怎么算不丢精度。先说BRAM省法,31×31窗口意味着你要同时拿到30个历史行和当前行共31行数据,但BRAM只能提供两个读口,所以常见做法是用双口BRAM加一个移位寄存器链做数据对齐——每个BRAM存一行,读口1给当前行,读口2给上一行,然后把读出的数据再打一拍送给下一级。这样31行只需要31个BRAM,比用移位寄存器省几千个LUT。深度上,每行存1920个像素就够了,1080P60的行消隐时间够你刷BRAM地址。累加器位宽要小心,很多人直接32bit完事,但面试官想听推导:输入8bit,窗口961个点,和最大值是8'd255961,约245k,需要18bit才能表示,但你还得考虑累加过程里中间结果不会超过这个值,所以累加器用18bit没问题,如果做两级流水(行累加+列累加),每级保持18bit,最后归一化前再扩到20bit防止舍入误差。代码框架上,建议先写一个参数化的行缓冲模块,然后用generate生成31个,再用一个组合逻辑做滑动窗求和。最后问一句,你目前对AXI4-Stream的ready/valid握手机制熟不熟?如果面试官让你现场写握手逻辑,那才是真正的坑点。

  • 芯片爱好者小陈

    31×31的窗口,行缓冲深度就是30行,每行存1920个有效像素。用BRAM比移位寄存器省资源,因为BRAM是专用存储块,大窗口下能省几千个LUT。具体做法是例化31个BRAM,每个深度设为图像宽度,用双端口读一写一,配合移位寄存器链做数据对齐。累加器位宽,输入8bit的话,窗口961个点,最大值是255961约245k,需要18bit,再加2bit防中间溢出,取20bit稳妥。代码框架建议拆成行缓存模块和滑动窗求和模块,别写在一起。你现在项目用的是Vivado还是Quartus?

  • Verilog新手村

    面试官让你手撕这个,其实是想看你有没有真正调过时序和资源,不是光知道公式。31×31的均值滤波,行缓冲的关键是怎么在BRAM双端口限制下拿到31行数据。每个BRAM只能提供两个读口,所以常见做法是:用30个BRAM分别存第2到第31行,每一行数据从BRAM读口1输出后,打一拍送给下一级BRAM的写口,同时读口2也输出同一行数据给累加器,这样每读一个新像素,就能拿到当前行和上一行的数据,配合一个单行移位寄存器存当前行,31行数据就齐了。BRAM深度取图像宽度,1080P60下每行1920个有效像素,但HDMI消隐区会导致实际行周期更长,你设成1920完全够用,地址用行计数器加像素计数器生成。累加器位宽很多人直接32bit,但面试官想听你推导:8bit输入,窗口961个点,最大和是255961=245055,需要18bit表示,但累加过程中中间结果不会超过这个值,所以累加器用18bit正好不溢出。如果你做两级累加——先横向累加再纵向累加,那横向累加器18bit,纵向累加器要18+log2(31)约23bit。代码框架上,我建议分三个模块:行缓冲模块用BRAM加移位寄存器链,滑动窗求和模块用流水线加法器树,最后归一化模块做移位除法。时序上,1080P60像素时钟148.5MHz,BRAM读延迟一拍,加法器树深度log2(961)约10级,流水线打够就能跑到200MHz以上。你目前是准备用纯逻辑实现还是打算调用DSP48做乘法?

  • 嵌入式小白

    其实导向滤波里均值滤波只是第一步,还有协方差计算和线性回归,但面试官只问均值滤波怎么省BRAM,说明他想先看你基本功。31×31的窗口,行缓冲深度30行没错,但有个细节:BRAM的读延迟会导致数据对齐问题。你读出一行数据后,直接送给下一级BRAM的写口,但读口2的数据要跟当前行数据严格对齐到同一个像素时钟周期,否则累加器算出来的值就错位了。解决办法是在BRAM输出后加一级寄存器打拍,让所有行数据延迟相同周期。另外,累加器位宽没必要取太大,18bit够用,但如果你用移位寄存器做行缓冲,LUT消耗会非常夸张——31行每行1920个像素,每个像素8bit,需要3119208约476k个LUT,而BRAM只需要31个,省了十倍不止。面试官还可能追问你怎么归一化,均值滤波除法可以用移位近似,因为31×31窗口像素数是961,不是2的幂次,但你可以先除以1024再补一个修正系数,或者直接用DSP48做除法。你项目里视频源是HDMI还是MIPI?接口时序会影响行缓冲的起始地址。

  • 嵌入式菜鸟

    我补充一个容易被忽略的点:均值滤波窗口越大,边界处理越麻烦。31×31窗口,图像四边各有15个像素的边界区域,均值滤波需要镜像或者补零。如果你用补零,行缓冲里要额外处理边界行的数据,BRAM深度至少加15。但面试官只问行缓冲和累加器,说明他默认你只处理有效区域。累加器位宽推导,我建议你直接写一个参数化模块,把窗口大小和数据位宽作为参数输入,内部自动计算位宽,这样代码复用性高。另外,去雾算法里均值滤波是算导向滤波的均值,不是最终结果,所以精度要求没那么高,18bit和20bit差别不大,但面试官更看重你推导过程是否严谨。你目前是打算用纯Verilog写还是用HLS?如果是手撕的话,建议先把行缓冲模块和累加器模块分开写,最后再拼起来,这样调试也方便。

  • 电子爱好者初级

    其实31×31这种大窗口,行缓冲深度就是图像宽度,比如1080P就是1920,深度30行。省BRAM的关键是别用移位寄存器——那个吃LUT吃到你怀疑人生。我建议直接用BRAM的简单双端口模式,每行一个BRAM,读口1按像素时钟读当前行,读口2读上一行,数据打一拍再送给下一级BRAM的写口,这样能凑齐31行数据。累加器位宽推导:8bit输入,961个点,最大和255961约245k,18bit够用,但为了防中间溢出可以加2bit取20bit。还有个细节:BRAM读延迟会导致数据对齐偏移,记得在读口后加寄存器打拍统一延迟周期。对了,你真写的时候,建议把行缓冲和滑动窗求和拆成两个模块,别全塞一个always块,否则时序收敛很难受。你目前是先写仿真再上板,还是直接上板调试?

  • 算法懵懂

    面试官让你手撕这个,核心是想看你有没有真正理解FPGA里的数据流和时序控制,不是光会背均值滤波公式。31×31窗口,行缓冲深度很好算:图像宽度+1或直接取图像宽度,因为每行有效像素固定,BRAM地址用像素计数器生成就行。但代码框架上有个容易被坑的点——BRAM的双端口读延迟。你用30个BRAM存历史行,每个BRAM读出一行数据要花一个时钟周期,读完后还要打一拍送给下一级BRAM的写口,这样所有行的数据到达累加器的时间会差好几个周期。解决办法是统一用三级打拍做对齐,类似流水线结构,让每行数据在进入累加器前都延迟相同拍数。累加器位宽的话,我建议分步算:先算一行内31个像素的和,再纵向累加31行。一行内用流水线加法器,每周期加一个像素,累加器位宽是输入位宽+5(因为31<32),纵向累加再加5,一共加10bit左右,比直接算961个点省资源而且时序好。另外,归一化这块很多人直接用除法器,但1080P60下除法器延迟大、资源多,你可以用移位近似,因为961接近1024,右移10bit就行,误差很小。最后提醒一句:如果你用纯Verilog手撕,建议先写一个参数化行缓冲模块,把窗口大小和位宽作为参数,这样下次面试官问5×5或7×7你直接改参数就行,不用重写。你现在是准备用Vivado的IP集成器还是纯手写RTL?

  • Verilog入门

    行缓冲深度就是图像宽度,BRAM比移位寄存器省资源,累加器20bit够用。别想太复杂,先让代码跑通再优化时序吧。

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

提问者

嵌入式小白查看主页
浏览「就业招聘」

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

相关问题

同分类

提问建议

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