2026年FPGA大赛用国产安路EG4做PCIe Gen2 x4数据采集卡,为什么上位机读到的DMA数据总是丢最后几个包,是描述符环没回收还是中断合并没关?

开放3 回答 125 浏览

我们队今年电赛选了高速数据采集方向,用安路EG4加外置PCIe硬核,上位机用XDMA驱动。现象是每次传输几MB后最后几个TLP包丢失,重传也不管用。查了描述符环状态,发现完成位有时候没置起来。是描述符环深度设小了,还是中断合并参数没关导致DMA提前停?有没有做过国产FPGA PCIe DMA的大佬指点一下排查顺序?

分享:

3 个回答

  • FPGA学员2

    先说结论方向:你描述的现象里「完成位有时没置起来」比「环深度不够」更值得先查,因为它直接指向写回路径而不是容量问题。丢最后几个包、重传无效,通常不是链路重传能救的,因为背压或提前停 DMA 是本地逻辑行为,重传只是把同样的错误再来一遍。

    按因果链捋一遍。描述符环本身要求基地址按环大小对齐,常见是 2 的幂对齐,比如 256 项就要 256×16 字节对齐。如果对齐没满足,硬核或驱动算出来的环回绕地址会错位,表现为跑到环尾附近完成位写不进去,正好是「最后几个包」丢。先确认这一点,用驱动打印环基址和项大小,手算一遍对齐。

    第二个高发点是完成位写回被优化掉。你在 RTL 里写 desc->status = DONE,如果这个写操作和后续读之间没有正确的时序约束,综合器可能把它当冗余逻辑删掉,或者跨时钟域没打拍导致偶尔丢写。用 ChipScope 或安路自家的在线逻辑分析仪抓写回总线的 valid/ready,看完成位那笔写到底有没有发出去。如果发出去了但上位机没看到,就是一致性或 cache 问题,XDMA 一般走的是非缓存映射,但要确认驱动有没有正确做写屏障。

    第三才是中断合并。中断合并参数没关,一般不会导致数据丢,只会让中断晚来,DMA 该搬的数据还是搬完了。但如果你的逻辑是「收到中断才启动下一轮搬运」,那合并阈值设大就会让最后一轮迟迟不启动,看起来像丢包。所以别一上来就关中断合并,先分清是「数据没搬」还是「搬了没通知」。

    排查顺序建议:先用抓包工具或 ChipScope 看 TLP 层,确认最后一笔 Memory Write 有没有真的发到上游;再看描述符完成位写回;最后才动中断合并和 MSI-X 向量分配。MSI-X 多向量分配如果和完成队列绑定错,也会让某些队列的中断永远不来。

    你们现在用的是安路官方 PCIe 硬核参考设计,还是自己改的 DMA 逻辑?这决定了环回收是硬核自动做还是你要手动写回。

  • EE新生

    先别急着调描述符环深度,这个现象更像是写回路径的问题。你想,如果是环深度不够,表现应该是整体吞吐上不去或者周期性卡顿,而不是「每次几MB之后固定丢最后几个包」。固定丢尾部,基本可以锁定在收尾逻辑上。

    我建议你按这个顺序排查。第一,确认描述符环的基地址和环大小是否满足 2 的幂对齐。硬核 DMA 往往要求环基址按环总字节数对齐,比如 256 项、每项 16 字节,那基址就得 4KB 对齐。对齐错了,回绕地址算出来会偏,最容易在环尾附近出现完成位写不进去,表现就是最后几个包没了。用驱动把 base address 和 item size 打出来,手算一遍。

    第二,查完成位写回有没有被优化掉。RTL 里写 desc->status = DONE 这种操作,如果和后续读之间没有正确的时序约束或者被当成冗余逻辑,综合器可能直接删。建议把状态写回单独用一个 always 块,加 keep 或者 dont_touch 属性,别让它和别的组合逻辑搅在一起。

    第三,中断合并。这个确实会让人误判,因为合并阈值设大了,看起来像 DMA 提前停了,但实际上数据已经写进内存,只是中断没来。你可以先把合并参数关掉,用最原始的方式验证一遍。如果关掉之后还丢,那问题就不在中断上。

    第四,MSI-X 向量分配。如果多个队列共用一个向量,收尾的中断可能被别的队列挤掉,导致你以为传输没完成。

    最后,如果以上都排除了,用 ChipScope 或者类似工具抓 TLP 层,看是不是主机侧背压导致硬核提前停 DMA。国产硬核在这块的流控行为和 Xilinx 不太一样,有时候 host 的 credit 没及时更新,硬核就自己停了。

    你现在用的是安路官方例程改的,还是自己从头搭的 DMA 逻辑?这个信息挺关键,例程改的话很多坑官方已经踩过了。

  • 技术新芽

    先别把注意力全放在环深度上,你这个「每次几MB后固定丢最后几个包、重传也没用」的现象,更像是本地收尾环节出了问题,而不是链路容量不够。重传无效这点很关键,说明丢包不是对端没发过来,而是你这边描述符回收或者DMA提前收工了。

    排查顺序我建议这么走。第一件事,把描述符环基地址和项大小打出来,手算一遍是不是满足2的幂对齐。安路的PCIe硬核跟Xilinx那套思路接近,环基址通常要求按环总字节数对齐,比如256项乘16字节,那基址就得4KB对齐。对齐错了,回绕地址算出来会偏,最容易在环尾附近完成位写不进去。第二件事,确认完成位写回有没有被综合器优化掉。RTL里 desc->status = DONE 这种操作,如果和后续读之间没有正确的时序约束,很容易被当成冗余逻辑删掉,表现就是「完成位有时候没置起来」。

    再往下才是你问的中断合并。中断合并阈值设太大,确实会让DMA看起来像提前停了,但它的典型表现是延迟变大、批量上报,而不是固定丢尾部几个包。这个维度可以作为第三步验证,不是首要嫌疑。

    补充一个容易被忽略的风险点:国产FPGA的PCIe硬核在跨时钟域写回描述符时,如果同步器级数不够或者写指针更新和读指针之间没有正确的握手,也会在环尾这种边界条件下偶发丢完成位。建议用ChipScope抓TLP层,重点看背压信号和完成写回的时间关系,而不是只看应用层计数。

    你们现在用的是安路官方XDMA参考驱动,还是自己改过的?这个信息会直接影响后面怎么定位。

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

提问者

芯片设计新人查看主页
浏览「其他」

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

相关问题

同分类

提问建议

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