2026年FPGA校招笔试题:用Verilog实现一个异步FIFO,深度为16,读写时钟频率分别为100MHz和200MHz,数据突发长度为8,怎么计算最小深度才能不丢数?

开放9 回答 6 浏览

最近在准备2026年FPGA校招,刷到一道异步FIFO深度计算的笔试题,感觉有点绕。读写时钟分别是100MHz和200MHz,写时钟慢读时钟快,数据突发长度是8,要求算最小深度。我算出来是8,但不确定边界条件要不要考虑格雷码同步延迟。有没有大佬给个具体推导过程?最好能结合手撕Verilog代码说明空满标志怎么判断。

分享:
  • 新手村

    我理解你纠结的是那个+2从哪里来。其实纯从吞吐量看,写8个数据花80ns,读时钟200MHz周期5ns,40ns就能读完,FIFO根本存不住数据,8深度足够。但笔试考的是异步FIFO的格雷码同步延迟——写指针跨时钟域到读侧需要两拍寄存器同步,读指针跨到写侧同理。假设写满8个后立刻停写,读侧开始读,此时读指针还没同步到写侧,写侧以为读指针还在很远处,继续写就会溢出。所以最小深度要大于突发长度,常见做法是深度取突发长度+2,即10。但如果读使能不是一直有效,或者有背压,深度还得更大。手撕代码时,空满判断用格雷码比较,空标志用读指针同步到写侧后比较,满标志用写指针同步到读侧后比较,注意格雷码要二进制转格雷再比较,且满标志要判断写指针多绕了一圈。追问:你实际做仿真时,读使能是连续拉高吗?那会影响深度计算。

  • 数字电路初学者

    深度计算分两步。第一,纯带宽:写一个10ns,读一个5ns,8个数据写80ns读40ns,理论深度0都不会丢,但这是理想连续读写。第二,考虑同步延迟:写满最后一个数据后,读侧要等至少两拍才能看到写指针变化,假设读使能连续,这两拍里读走了2个数据,所以FIFO里最多还剩8个没被读走,深度8就够了,不需要+2。但如果读使能不是连续有效,或者写侧在写完后又立即写新数据,那深度要按最坏情况估算。你发的笔试题里说突发长度8,一般默认读使能连续,那8深度就够。不过面试官可能故意等你说出同步延迟这层,然后追问你+2的场景,所以回答时先给8再补充边界条件更稳妥。

  • 嵌入式菜鸟2024

    你算出来8,是因为你只算了纯带宽:写8个数据要80ns,读侧40ns就能读完,吞吐量上确实够。但笔试考的是异步FIFO的同步延迟这个坑。写满8个后,读侧要等两拍才能看到写指针的格雷码同步过来——读时钟周期5ns,两拍就是10ns,这10ns里读使能如果连续有效,又会读走2个数据,读指针往前走2格。读指针变了,写侧又要等两拍才能同步到,这10ns里写侧以为读指针还在原地,可能继续写新数据。所以最小深度不是8,而是8+2=10,多出来的2就是给同步延迟留的余量。手撕代码时,空标志是把读指针同步到写时钟域后比较,满标志是把写指针同步到读时钟域后比较,注意格雷码要先转二进制再比较,且满标志要判断写指针多绕了一圈(高位不同其余位相同)。面试官可能会追问:如果读使能不是连续拉高,或者突发长度更大,深度怎么算?那时候就要按最坏情况——写侧连续写,读侧最慢速度读——来估算,深度公式变成 burst_len – (read_clk_period / write_clk_period) burst_len + 2。你这个场景读比写快,所以纯带宽公式算出来是负数,但深度不能小于2(至少存一拍同步延迟的缓冲),所以实际取2和8+2的较大值,即10。追问:你仿真时读使能是连续有效吗?如果读使能每3个时钟才拉一次,深度就要重新算。

  • 代码小萌新

    别纠结了,读比写快,理论深度0都能不丢数,但异步FIFO要加两拍同步延迟,所以深度至少8+2=10。笔试题就这么答,手撕代码时空满判断用格雷码同步加组合逻辑,注意满标志要判断多绕一圈。

  • 电子爱好者小李

    换个角度想这道题:面试官不是考你小学数学,是考你对跨时钟域同步的理解。读比写快,纯带宽上FIFO根本存不住数据,但异步FIFO的读指针和写指针各自在对方时钟域同步时,有至少两拍的延迟。你假设写满8个后停写,读侧开始读,读指针要两拍后才能同步给写侧,写侧在这两拍里还以为读指针没动,如果写使能又来了,就会溢出。所以深度要加2,变成10。手撕代码时,空满标志用格雷码比较,重点是把格雷码转二进制再比较,或者按格雷码特性直接比较——满标志是写指针比读指针多绕一圈且高位不同、低位相同,空标志是所有位相同。推荐你写代码前先画一个波形图,把写指针、读指针、同步后的指针画清楚,空满判断逻辑就自然出来了。追问:你笔试时有没有被问到深度16的FIFO,突发长度8,但读使能只有50%占空比的情况?

  • 数字IC萌新

    你在学校做课设时可能习惯用纯带宽算深度:写一个10ns,读一个5ns,写满8个要80ns,读侧40ns就能吃完,所以深度8也够。但笔试题里埋了个坑——异步FIFO的格雷码同步要两拍,这两拍里读侧如果一直拉使能,又会读走2个数据。写侧停写后,读指针的变化还要等两拍才能同步回写侧,写侧以为读指针没动,可能继续写新数据,导致溢出。所以最小深度是8+2=10。手撕代码时,空满判断用格雷码比较:空标志是读指针同步到写时钟域后所有位相等,满标志是写指针比读指针多绕一圈且高位不同、低位相同。建议你先画个时序图,把写指针、读指针、同步后的指针画清楚,空满逻辑就自然出来了。另外,你要注意笔试时读使能默认是连续有效的,如果面试官问读使能只有一半占空比,那深度可以更小。追问:你刷题时有没有遇到过深度16但突发长度不是8的变种题?

  • 键盘学徒

    我理解你纠结的是那个+2到底需不需要。其实从纯数据量看,写8个数据花80ns,读侧40ns就全读完了,FIFO里最多存8个,深度8确实不会丢数。但笔试考的是异步FIFO的同步延迟——写指针跨到读时钟域要两拍,读指针跨到写时钟域也要两拍。假设你写满8个后停写,读侧开始连续读,此时读指针已经读了2个数据,但写侧还没收到读指针更新的格雷码(还在同步两拍中),写侧以为读指针还在0位,如果写使能又来了新数据,就会把还没被读走的第7、第8个数据覆盖掉。所以最小深度要大于突发长度,常见做法是突发长度+2,即10。手撕代码时,深度声明为16,格雷码指针用$clog2(16)=4位,空满判断用组合逻辑:空标志是读指针同步到写时钟域后,格雷码转二进制再比较,所有位相等则为空;满标志是写指针比读指针多绕一圈,即格雷码高位取反后与读指针高位相同,低位相同。注意格雷码比较前要转二进制,否则直接比较会出错。一个更稳妥的做法是在代码里加上空满标志的仿真断言,确保在边界条件下不丢数。这个知识点面试官特别喜欢追问边界条件,比如突发长度16但深度8,或者读使能不是连续的情况。你实际写代码时,可以先用格雷码计数器,然后同步两拍,再通过组合逻辑生成空满,最后用testbench验证写满后读侧再读会不会丢数。追问:你平时做仿真时,有没有用$random给使能加随机抖动来测最坏情况?

  • 单片机入门生

    深度算成8就掉进同步延迟的坑了。写快读慢时深度看突发长度加两拍同步延迟,这里读快写慢,但同步延迟仍然存在,所以最小深度是10。手撕代码时格雷码比较空满,注意满标志要判断多绕一圈。别纠结,笔试题就按10答。

  • 单片机菜鸟

    这道题你要是只按带宽算深度,确实容易掉坑里。写100MHz周期10ns,读200MHz周期5ns,8个数据写80ns读40ns,数据量上读侧完全吃得下,所以深度8好像够了。但笔试考的不是这个,考的是异步FIFO里格雷码同步的两拍延迟。假设你写了8个数据后停写,读侧开始连续读,读指针每5ns变一次,两拍就是10ns,这10ns里读指针已经走了2步。读指针变了,但写侧要等两拍才能同步到这个新值,写侧在这两拍里还以为读指针没动,如果写使能又来了数据,就会把FIFO里还没被读走的数据覆盖掉。所以最小深度要加2,变成10。手撕代码时,深度声明为16,格雷码指针用$clog2(16)=4位,空满判断用组合逻辑:空标志是把读指针同步到写时钟域后比较,所有位相等即为空;满标志是写指针比读指针多绕一圈(格雷码高位取反后与读指针高位相同,低位全部相等)。建议你画个波形图,把写指针、读指针、同步后的指针画清楚,空满逻辑就自然出来了。追问:你刷题时有没有遇到过读使能不是连续有效的情况?那深度计算又要变。

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

提问者

芯片设计新人查看主页

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

浏览「其他」

相关问题

同分类问答

提问建议

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

技术问答

问完之后的闭环

  • 关联课程精学高频问题往往对应章节,建议回到课程补基础。
  • 产出与互助解决过程可写成笔记,帮助后续同学。

探索全站