面试官让我算一个写时钟100MHz、读时钟80MHz、写侧每100个周期突发写80个数据的异步FIFO最小深度。我背过「深度=突发长度-读侧能读出的数据量」,但一紧张就忘了怎么推。想请教这种题有没有通用的推导步骤?面试时应该先问清楚哪些参数再动笔?
2026年FPGA校招面试被问「你项目里FIFO深度是怎么算的」,只会背公式不会结合突发长度推导,该怎么补?
11 个回答

先说结论:这种题别死背公式,按「先把时间轴统一,再看谁快谁慢」去推。写侧100MHz,100个周期就是1us;这1us里写进80个数据。读侧80MHz,1us能读80个,但注意突发是连续写的,读侧同时也在读。你可以这样想:最坏情况是读侧在突发开始前刚好没在读,或者读时钟比写慢,导致积累。更通用的步骤是:第一,问清楚突发长度W、突发周期T、读写频率;第二,算一个突发窗口内写进多少、读走多少;第三,深度至少等于累积差。你给的例子里,100个写周期=1us,写80个;读侧1us读80个,看似够,但实际要考虑读侧可能延迟启动。面试时先确认「读侧是否在突发期间持续读」「有没有空闲周期」,再动笔。
你现在是卡在公式记忆还是时间轴换算上?

我建议你别再背那句话了,换成一根时间轴去推。先把写侧的突发窗口算出来:100个写周期,100MHz,就是1微秒;这1微秒里写进去80个数据。再看读侧:80MHz,1微秒能读80个,理论上刚好追平。那为什么还常要留深度?关键是读侧不一定从突发第一拍就开始读,可能仲裁晚了几拍、或者读使能有间隔。所以最小深度的本质是「这段窗口里写进来的减去确定能读走的」。面试时你先别急着算,先问三件事:突发长度和周期是多少、读侧在突发期间是否连续读、读写时钟各自频率。把这三个问清楚,再列窗口内写多少读多少,最后求差值。你现在是卡在时间单位换算,还是不确定读侧要不要按满速算?

这题其实不用背公式,你只要把「一个突发窗口」当成一个账本。先问面试官三个参数:写时钟频率、突发里真正写数据的拍数、读时钟频率,以及读侧在这段时间是不是连续读。以你给的数为例:100MHz写,100个周期是1微秒;这1微秒里只写进去80个数据。读侧80MHz,1微秒最多读80个,听起来刚好追平,但关键是读侧不一定从第一拍就开始读,可能晚几拍、或者中间有间隔。所以最小深度等于「这段时间写进来的」减去「确定能读走的」。面试时别急着报数,先把窗口画成一条时间轴,标出写入区间和读取区间,再求差值。平时练的时候,换几组数字自己推,比背结论有用得多。你现在是卡在时间单位换算,还是不确定读侧要不要按满速算?

先别急着套公式,动手画一条时间轴最快:100MHz下100周期就是1us,这1us里写进80个;读侧80MHz在同样1us最多读80个。差距不在算术,而在读侧是不是从第一拍就读、中间有没有空拍。面试时先问这两点,再谈深度。你现在是时间换算不熟,还是不确定读侧要不要按满速算?

其实这类题的通用思路就一句话:看一段最坏窗口里,写进来多少、确定读走多少,差值就是深度下限。你例子里写侧100MHz、100周期突发写80个,窗口是1us,写进80;读侧80MHz理论上1us读80,账面刚好打平。但真实设计里读侧往往不会在突发第一拍就满速读,仲裁、跨时钟同步、读使能间隔都会吃掉几拍,所以深度通常还要留余量。面试时先确认三件事:突发长度和周期、读写时钟频率、读侧在突发期间是否连续读。把窗口内的写入量和确定读走量列出来,再相减。平时练习就改数字自己推,比背结论稳。

我当年也被这题问懵过,后来发现真正要补的不是公式,而是「先问参数再算」的习惯。你可以给自己定个三步:第一步问清突发结构,比如每100个写周期里写80个,周期是100还是别的;第二步问读侧行为,是突发期间一直读,还是读几拍停几拍,会不会延迟启动;第三步才是统一时间单位算差值。拿你给的数来说,100MHz下100周期是1us,写进80个;80MHz读侧1us最多读80个,看似够,但如果读侧晚启动或中间有空隙,实际读走就不到80,深度就得往上加。风险在于很多人只按满速读去算,面试官一追问读侧延迟就露馅。替代做法是把读写都画成时间轴,标出写入区间和读取区间,取最坏重叠情况求累积差。练习时换几组数字,比如读时钟改成60MHz、突发改成每200周期写150个,自己推一遍就通了。你目前是卡在时间单位换算,还是不确定读侧要不要按满速算?

先说个我自己的教训:当年我也背过那句公式,结果面试官把突发改成每200周期写150个,我当场就懵了。问题不在公式本身,在于你把它当结论记,而不是当过程推。这类题真正的通用步骤只有一条主线:把「一个突发窗口」看成一个时间账本,先算这段时间里写进来多少,再算这段时间里确定能读走多少,差值就是深度下限。
为什么强调「确定」?因为面试官想考的不是算术,是你对最坏情况的理解。写侧是主动方,突发来了就一定要写;读侧是被动方,什么时候开始读、能不能连续读,往往不由你说了算。所以推导顺序应该是:先定写侧的窗口,再问读侧的约束,最后才做减法。
具体到你给的数:写时钟100MHz,100个周期是1微秒,这1微秒里写进80个数据。读时钟80MHz,1微秒理论上能读80个,账面刚好打平。但「打平」在工程里等于危险,因为读侧只要晚启动几拍,或者读使能中间有空隙,累积差就出来了。所以面试时别急着报数,先问三件事:突发长度和周期是多少、读侧在突发期间是否连续读、读侧有没有启动延迟或仲裁开销。问清楚再动笔,这本身就是加分项。
补的方法我建议按里程碑走:第一步,拿纸画时间轴,横轴是时间,标出写入区间和读取区间,先不管公式;第二步,换数字自己推,比如读时钟改成60MHz、突发改成每200周期写150个,推三组就形成肌肉记忆;第三步,回到项目里,把你自己FIFO的实际读写时序画出来,看看当初深度是怎么定的,能不能复现。
最后提醒一句,公式可以忘,但「先问参数、再看最坏窗口、最后做减法」这个习惯不能丢。你目前是卡在时间单位换算,还是不确定读侧要不要按满速算?

我当年也背过那个公式,后来发现真正的问题不在公式,在于我没搞懂「为什么要减」。你换个角度想:FIFO 存在的唯一理由,是写侧和读侧在某一小段时间里速率对不上,缓冲区就是拿来吸收这个落差的。所以任何 FIFO 深度题的骨架都是一句话:在一段最坏的时间窗口里,写进来多少、确定能读走多少,差值就是深度下限。注意「确定」两个字,这是面试官真正想听的。
拿你这题走一遍。写侧 100MHz,一个周期 10ns,100 个周期就是 1us,这 1us 里写进 80 个数据。读侧 80MHz,一个周期 12.5ns,1us 理论上能读 80 个。账面上刚好打平,但打平在工程里等于危险,因为读侧几乎不可能从突发第一拍就满速、连续、零延迟地读。仲裁要几拍、读使能有间隔、跨时钟握手有延迟,这些都会让实际读走的数量小于 80。你减掉的那个「读侧能读出的量」,指的是最坏情况下它至少能读走多少,而不是理想值。
所以正确的动笔顺序是:先定写侧窗口,再问读侧约束,最后做减法。面试时别急着算,先确认三件事:突发结构到底是不是每 100 个周期写 80 个、这 100 个周期里剩下的 20 拍是完全不写还是有别的行为;读侧在这段窗口里是不是持续读、会不会延迟启动或中间有空拍;读写时钟频率是否就是题面给的这两个。这三个问清楚,题目才从「背过的题型」变成「你现场推的问题」,面试官也会觉得你有工程意识。
补的方法我建议别刷题,改成自己造题。拿一张纸画时间轴,横轴是时间,上面画写侧的突发区间,下面画读侧的读取区间,把最坏重叠情况标出来,累积差的最大值就是深度。然后自己改数字:读时钟改成 60MHz 会怎样、突发改成每 200 周期写 150 个会怎样、读侧每读 4 拍停 1 拍会怎样。推五六组,你会发现公式根本不用记,因为它就是从这张图上长出来的。你现在是时间单位换算容易乱,还是不确定读侧该按哪种行为去算?

这类题我后来才想明白,面试官想看的其实是你有没有「先定窗口、再算差额」的直觉,而不是那个减号。给你一条主线:把异步FIFO当成一个漏水桶,写侧是进水龙头(间歇性猛灌),读侧是出水口(可能慢、可能晚开),深度就是桶里最坏情况下积起来的水量。所以推导只做三件事——定一个最坏时间窗口、算这窗口里灌进去多少、算这窗口里确定能放走多少,一减就是下限。
拿你这题走一遍。写侧100MHz,一个周期10ns,100个周期就是1us,这1us里灌进80个。读侧80MHz,一个周期12.5ns,1us理论上能放走80个。账面刚好打平,但打平在工程里等于危险,为什么?因为读侧几乎不可能在突发第一拍就满速、连续、零延迟地放水。仲裁要几拍、读使能有间隔、跨时钟握手有延迟,这些都会让实际放走的少于80。所以真实的深度下限是「80减去确定能放走的」,而不是「80减去理论上能放走的」。面试时你可以主动把这个说出去:账面是0,但我一般会再留几拍余量,具体留多少取决于读侧最坏延迟。
再补一层你可能没意识到的:窗口怎么选,本身就是考点。如果读侧在突发开始前就已经在读,那窗口内读走的会更多,深度可以小;如果读侧是突发结束后才启动,那几乎全部80个都要先攒下来,深度就接近80。所以「读侧什么时候开始读」这个参数比频率更关键,很多人只盯着两个频率算,反而漏了真正的变量。
补的方法我建议别刷题海,做三件事就够。第一,把这道题的读写过程画成两条时间轴,标出写入区间和读取区间,自己找最坏重叠,画三遍就成肌肉记忆了。第二,换参数自己出题:读时钟改成60MHz、突发改成每200周期写150个、读侧加2拍延迟,各推一遍,你会发现自己哪一步是真的懂、哪一步还在套。第三,面试前准备一句万能开场:「我先确认几个参数再算」——突发长度和周期、读写频率、读侧在突发期间是否连续读、有没有启动延迟。把这四问说出口,面试官对你的评价立刻不一样。
你现在是卡在时间单位换算,还是不确定读侧要不要按满速算?

别纠结公式了,就记一个画面:突发期间写侧拼命灌,读侧同时在漏,桶里剩多少就是深度。你这题写侧1us灌进80个,读侧1us最多漏80个,理论上刚好,但读侧一般不会从第一拍就满速漏,所以实际深度得按「80减去确定漏掉的」来算,通常还要加几拍余量。面试时先问四件事:突发多长、周期多长、读侧是否连续读、有没有启动延迟。把读写画在一条时间轴上找最坏重叠,比背结论稳得多。你目前是换算不熟还是读侧行为拿不准?
发表回答
登录后可在本页底部提交回答