我今年秋招面了海思,面试官让手撕Verilog实现AXI4-Stream实时视频去雾,暗通道先验算法。透射率t(x)计算涉及除法,用查找表替代乘法器能省DSP。但我不确定查找表深度和位宽怎么定,以及BRAM消耗对比。求大佬给出具体推导公式和资源对比,比如用128深度LUT和256深度LUT的区别。
2026年FPGA校招,面试官问手撕Verilog实现AXI4-Stream实时视频去雾,暗通道先验中透射率t(x)怎么用查找表加速?求具体推导和资源对比
12 个回答

面试官让你手撕透射率除法变查表,本质上是在考你两件事:把浮点运算映射到整数域的能力,以及BRAM vs DSP的trade-off意识。先说推导,暗通道先验里t(x)=1-ωmin(I/A),其中I是暗通道值,A是大气光。你把A归一化到0-255,那么min(I/A)就能用I除以A的整数商近似,但除法器在FPGA里要么占DSP要么占大量LUT。正确做法是预计算一个256深度、16位宽的查找表,地址是I(0-255),表里存的是1-ω(I/A)的定点结果,比如Q8.8格式。这样每个像素只需一次查表加一次乘法(如果ω需要乘的话)。资源上,256×16的BRAM用一块4Kb的BRAM18就够,比直接调用除法器省2个DSP48E1,代价是多用1个BRAM。面试时你要主动指出:对于1080p实时视频,查表延迟固定1个时钟周期,而除法器至少3-4个周期,流水线深度不同。如果他用128深度,地址是I>>1,精度损失在暗通道值较大时明显,因为暗通道在低亮度区导数变化快。另外注意A的更新频率——如果每帧都重算A,你得在帧消隐期刷新BRAM内容,否则查表值会错。常见误区是把查找表做成ROM直接固化,但真实系统里A随场景变化,必须做成可写RAM。追问:你准备用单口还是双口BRAM?双口可以同时查表和更新系数,但会多占一个BRAM的额外端口逻辑。

除法转查表,深度选256还是128取决于你对t(x)精度的容忍度。256深度对应直接映射I[7:0],128深度需要把I右移1位,相当于用高位地址。代价是t(x)的量化步长翻倍,在暗通道值小的区域误差可能超过5%,而视频去雾对暗区误差很敏感,容易出现色块。BRAM方面,256×16用1个BRAM18,128×16用半个BRAM18但无法独立使用,实际还是占一整块。所以从资源角度看128深度不划算,精度降了但省不了BRAM。面试官更想听你分析这个取舍,而不是直接给结论。

查表深度256,位宽16,一块BRAM搞定,省两个DSP。128深度省不了BRAM还丢精度,别用。面试官考的是你愿不愿意为省DSP多占BRAM,直接选256就好。

面试官让你现场推透射率查表,其实重点不在除法转乘除的数学本身,而在你能否把算法对视频流的影响说出来。你推导时先写t(x)=1-ωmin(I/A),然后说A是大气光,通常在预处理阶段用直方图统计出最大值,归一化到0-255。查表深度选256是因为暗通道值I本身就是8bit,直接映射省掉地址换算逻辑,延迟少一个周期。位宽16bit是因为t(x)是浮点,你需量化成Q8.8格式,高8bit整数部分几乎用不到(t(x)范围0-1),但保留整数位方便后续乘法做饱和截位。资源上,256×16用一块BRAM18刚好,如果选128深度,地址要右移一位,等效于损失1bit精度,暗通道值小于128的区域误差会被放大,视频去雾里天空和白色物体边缘容易偏色。还有个风险——BRAM18在Xilinx 7系列里最小规格是18Kb,一块BRAM18要么配置成512×32要么256×16,128×16虽然只用一半但没法释放另一半,实际还是占满一块。所以128深度既省不了资源又降精度,面试官更想听你分析这个取舍,而不是直接说选256。另外,你可以在手撕代码时主动提一句:查表后t(x)要跟原图做乘法和加法恢复无雾图,乘加都用DSP48E1,这样DSP省了两个但BRAM多占一块,整体资源占用持平,但时序更好因为查表是单周期。追问一句:你准备用哪家的FPGA?如果是Lattice或国产小芯片,BRAM可能只有4Kb块,256深度一块放不下,那时就得分拆成两个小LUT,或者降位宽到12bit,面试官会等你主动说这个变通。

别光盯着BRAM和DSP的个数对比,你得想清楚面试官为什么要在手撕环节问这个。暗通道先验去雾里,透射率t(x)的计算涉及min(I/A)这个除法,而min操作在FPGA里其实可以用多级比较器流水实现,真正卡时序的是除法。你回答查表方案,本质上是在考你能否把连续浮点函数离散化并映射到存储资源上。推导时先写t(x)=1 – ω (I / A),其中I是暗通道值(0-255),A是大气光值(假设已统计出为128左右)。你把I/A拆成查表,表地址是I,表里存的是1 – ω (I / A)的定点数。深度选256是因为I的取值空间就是256,地址无需编解码,直接拿I的8bit接BRAM地址口,零额外逻辑。位宽选16是因为t(x)的精度需求——如果位宽8bit,量化步长1/256≈0.004,误差在暗区可能超过5%,导致去雾后暗部细节丢失;16bit用Q8.8格式,步长1/65536,精度足够。资源上,256×16在Xilinx BRAM18里刚好占一个块(18Kb),如果选128深度,地址少1bit,但BRAM18最小粒度是18Kb,你省不了资源,反而因为地址右移导致I值在128以下时t(x)误差翻倍,比如I=1时真实t≈0.99,128深度查表会错误映射到I=0对应的t≈1.0,误差1%。面试官更想听你指出这个非线性误差——暗通道先验里I值小的区域对应近景或浓雾,误差会放大去雾后的偏色。所以结论是256深度是唯一合理选择。另外,你还可以补充另一种思路:如果A不是常数而是逐帧更新,那查表内容也要跟着变,这时可以用分布式RAM(LUTRAM)代替BRAM,但LUTRAM容量小,256×16需要4个LUTRAM(每个64×1),资源上不如BRAM划算。追问一句:你面试时有没有被追问A的更新频率?如果A每帧变化,查表的重载逻辑怎么写?

256深度,16位宽,一块BRAM,省两个DSP。128深度省不了BRAM还丢精度,别纠结。面试官考的是你愿不愿意为省DSP多占BRAM,直接选256就好。

面试官考你查表替代除法,本质是想看你对浮点转定点的量化误差有没有直觉。256深度是因为暗通道值I就是8位,地址直接映射,不需要额外逻辑。位宽选16是因为t(x)范围0到1,用Q8.8格式,高8位整数部分虽然几乎全是0,但保留整数位能让后续乘法做饱和截位更简单,不丢精度。资源上256×16刚好塞进一块BRAM18,128深度反而尴尬,地址要移位,精度损失在暗区会放大,去雾时天空边缘容易偏色。面试时你主动提一句,对于1080p 60fps的视频流,查表延迟固定一个时钟,比除法器省两个DSP48E1,代价是多占一个BRAM,这个交换是划算的。

其实你在面试手撕时,不用一上来就写Verilog,先把数学推导写白板上。透射率t(x)=1-ωmin(I/A),其中I来自暗通道图,A是大气光值。你把A归一化到0-255,比如取128,那么I/A就是一个0到2之间的数。除法在FPGA里要么用DSP做除法器,要么用CORDIC,都吃资源。正确做法是预计算一张表,地址宽度8位对应I,数据宽度16位存t(x)的定点数,比如Q4.12格式。这样每个像素只需一次读BRAM,省掉除法器。资源上,256×16用一块4Kb BRAM,128×16虽然数据量减半,但BRAM18的最小粒度是4Kb,省不下来,反而因为地址需要右移一位,导致低1位信息丢失,暗区误差可能从1%跳到5%以上。面试官更在意你有没有意识到这个trade-off,而不是单纯背结论。另外提醒一点,海思面试喜欢追问时序,你最好提一句查表路径可以流水打一拍,避免组合逻辑过长。

兄弟你问的这个点挺关键的,秋招面试手撕环节里,暗通道先验的除法转查表几乎是必考点,但很多人只背了结论,没想透背后的工程取舍。我当初面某家做ISP的芯片公司时,面试官直接让我在黑板上推导资源公式,还追问了BRAM的位宽利用率。这里我展开说几个容易踩的坑。第一,深度选256而不是128,表面看是精度问题,实际是BRAM的物理结构决定的。Xilinx 7系列BRAM18的深度是512,宽度是18位,你配置成256×16刚好用一半,剩下的一半可以被另一个查表复用,但128×16只占四分之一,剩下的四分之三无法独立分配给其他模块,所以从利用率角度,128深度既浪费BRAM又浪费精度。第二,位宽16位不是拍脑袋,你要算量化误差。t(x)是0到1之间的浮点数,如果用8位量化,步长1/256≈0.004,在暗通道值很小的区域,比如I=10,A=128,真实t≈0.92,量化后误差0.4%,看起来不大,但去雾公式里t(x)出现在分母,误差会被放大,导致暗区出现色阶。16位量化步长1/65536,基本可以忽略。第三,面试官还可能问你为什么不直接用乘法器实现除法,比如把1/A预计算成定点数,然后每次用乘法加移位。这个做法需要两个DSP48E1,一个做乘法,一个做后续的饱和与截位,比查表多两个DSP,但少一个BRAM。对于资源紧张的FPGA,比如只有几十个DSP的设计,查表方案更优;相反如果BRAM吃紧,用乘法器方案也行。你面试时最好主动说清这个取舍,而不是只给一个结论。最后提一句,实际工程中A不是固定值,每帧都可能变,查表需要每帧更新,这会引入BRAM写端口冲突,建议用双端口BRAM,一个端口给查表读,另一个端口在帧消隐期更新表内容。你如果能在面试时把这个细节讲出来,面试官会觉得你真有流片经验。你现在做的是纯FPGA实现还是带软核的SoC方案?这会决定你更新表头的实现方式。

面试官问查表深度,你直接说256,理由是暗通道值是8bit,地址零开销。位宽16bit是Q8.8格式,后续乘加不用扩位。别扯128深度,省不了BRAM还丢精度,面试官一听就知道你踩过坑。
发表回答
登录后可在本页底部提交回答