FPGA数据搬运实战:AXI/AXIS、DMA与DDR缓存架构设计

发布时间:2026/10/19 1:06:39
FPGA数据搬运实战:AXI/AXIS、DMA与DDR缓存架构设计 1. 从数据怎么进去、怎么出来说起为什么Part.23是整个FPGA项目里最容易被低估的一环做FPGA开发做到一定阶段你会发现一个很有意思的现象前面二十来篇把流水线、状态机、时序约束、跨时钟域都啃下来了仿真波形也漂亮得不行结果一上板子数据量一大就崩——要么吞吐上不去要么数据对不上要么干脆整个系统卡死。问题往往不在算法本身而在于数据搬运这条链路没设计好。这一篇要聊的就是这个搬运问题AXI/AXIS总线怎么用、DMA什么时候该上、DDR缓存架构怎么规划。关键词是AXI、AXIS、DMA、DDR缓存、数据搬运、突发传输、带宽匹配。如果你正在做一个需要把大量数据从外部送进FPGA、处理完再送出去的项目比如图像处理、高速采集、实时信号分析那这篇内容基本就是你绕不过去的一道坎。我先把结论摆前面算法决定你能做多好数据通路决定你能不能做出来。很多新手把90%的精力花在算法模块上最后发现真正拖垮项目的是那个看起来很简单的数据搬运环节。这篇就按我实际踩过的顺序把AXI/AXIS、DMA、DDR缓存这三块讲透包括为什么这么选、参数怎么算、坑在哪里。适合谁看已经能写基本Verilog/VHDL、跑过几个小项目、现在要接触真实数据通路的开发者。纯零基础也能看但建议先把前面Part.1到Part.22的基础过一遍。2. AXI和AXIS到底差在哪别再把两者混着用了2.1 一个管地址一个管流刚接触这两个协议的人最容易犯的错就是把AXI和AXIS当成同一个东西的两种写法。实际上它们的设计目标完全不同。AXIAdvanced eXtensible Interface是带地址的存储器映射总线。它的核心特征是每一次传输你都要给出一个地址从设备根据地址去读写对应的存储位置。你可以把它理解成快递送货——你得写清楚送到哪个门牌号地址快递员才知道往哪放。AXISAXI4-Stream是没有地址的流式总线。它只管把数据从A点推到B点不关心数据存哪。就像传送带——东西放上去就一直往前流没有门牌号的概念只有什么时候有效TVALID和我准备好了TREADY。这个区别决定了它们的应用场景特性AXI存储器映射AXIS流式地址有每次传输带地址无典型用途访问DDR、寄存器、BRAM模块间数据流、DMA数据通道握手信号VALID/READY 地址通道仅VALID/READY突发支持支持但需地址对齐天然连续流反压机制通过READY通过TREADY我见过太多项目在模块之间硬用AXI传数据结果每个数据都要算地址、发地址通道逻辑资源浪费一大半时序还难收敛。模块内部的数据流动一律优先用AXIS只有需要访问具体存储位置时才用AXI。2.2 五个通道别只盯着数据通道AXI之所以重是因为它把读写拆成了五个独立通道读地址通道AR发起读请求给出地址读数据通道R返回读出的数据写地址通道AW发起写请求给出地址写数据通道W送出要写的数据写响应通道B从设备告诉你写成功了新手常犯的第二个错只关心数据通道忘了写响应通道B。结果写操作发出去了但没等B响应就继续下一笔导致数据覆盖或者顺序错乱。写操作必须等B通道返回BRESP才能确认完成这是硬性要求。读操作相对简单AR发出去R通道把数据带回来RLAST标记这一笔突发的最后一个数据。但要注意读数据和读地址是解耦的你可以连续发多个AR数据会按顺序回来但中间可能有延迟。设计时要考虑outstanding未完成请求的数量。2.3 突发长度和位宽带宽计算的第一课AXI的突发传输burst是提升效率的关键。一次突发可以连续传多个数据地址只发一次。突发长度burst length通常是2到256拍。带宽怎么算公式很简单理论带宽 数据位宽(bit) × 频率(MHz) × 每周期传输次数 / 8 (单位MB/s)举个例子128位数据位宽200MHz时钟每个时钟周期传一次那么128 × 200 / 8 3200 MB/s 3.2 GB/s但这是理论峰值。实际能跑到多少取决于突发效率、outstanding数量、DDR的实际吞吐。经验值实际带宽通常是理论值的60%到80%如果你的设计需要3GB/s那理论带宽最好按4GB/s以上去规划。提示突发长度不是越长越好。太长的突发会增加延迟影响实时性太短则地址开销占比高效率低。一般64到128拍是比较平衡的选择。3. DMA让CPU和FPGA都别干搬砖的活3.1 为什么必须上DMA先说一个反直觉的事实在很多FPGA系统里最慢的环节不是算法而是数据搬运本身。假设你要处理一帧1080p的图像1920×1080×3字节RGB大约是6MB。如果用CPU一个字节一个字节地搬就算CPU主频3GHz每周期搬4字节理论也要50万周期实际因为访存延迟可能要几毫秒。而FPGA处理这帧图像可能只需要几百微秒。搬运时间比处理时间还长这就本末倒置了。DMADirect Memory Access直接存储器访问就是来解决这个问题的。它的核心思想是让一个专门的硬件模块去搬数据CPU和算法模块都不用管。CPU只需要告诉DMA从哪搬到哪、搬多少然后就可以去干别的事DMA搬完了发个中断通知。在FPGA里DMA通常由厂商提供的IP核实现比如Xilinx的AXI DMA、AXI VDMA视频专用、或者自己用AXISAXI写一个简单的搬运引擎。3.2 三种DMA模式选错了性能差十倍以常见的AXI DMA IP为例它有三种工作模式Simple DMA模式一次传输配置一次传完就停。适合小数据量、低频次的场景。缺点是每次都要CPU介入配置开销大。Scatter-GatherSG模式预先在内存里建一个描述符链表每个描述符记录一段数据的源地址、目的地址、长度。DMA自己遍历链表连续搬运多段数据。这是大数据量、连续流场景的首选。CPU只需要配置一次链表头剩下的DMA自己搞定。Cyclic模式SG模式的循环版本链表走完自动回到开头。适合持续不断的采集流比如音频、视频。我个人的经验只要数据量超过几KB或者需要连续搬运直接上SG模式。Simple模式看起来简单但在真实项目里很快就会成为瓶颈。3.3 描述符链表的坑对齐和缓存一致性SG模式虽然强大但描述符链表本身有两个大坑。第一个坑是地址对齐。AXI DMA通常要求描述符的地址按一定字节对齐比如64字节。如果你在软件里随便malloc一块内存当描述符很可能不对齐DMA直接罢工。解决办法是用对齐分配函数或者手动对齐。第二个坑是缓存一致性cache coherency。这是最隐蔽的坑。CPU写描述符时数据可能还在CPU的cache里没写到DDR。DMA去DDR读描述符读到的是旧数据。反过来DMA把数据写到DDRCPU去读可能读到cache里的旧值。解决方式有两种软件维护CPU写完描述符后手动flush cacheDMA写完后CPU读之前invalidate cache。麻烦但可控。硬件维护用带cache一致性的互联如ACE接口硬件自动保证。省心但需要平台支持。注意如果你在调试时发现DMA有时候工作有时候不工作十有八九是缓存一致性问题。这种间歇性bug最难查一定要在架构设计阶段就考虑清楚。3.4 中断还是轮询实时性的取舍DMA搬完数据后怎么通知CPU两种方式中断DMA发中断CPU响应。优点是CPU不用一直等效率高。缺点是中断有延迟几微秒到几十微秒且中断处理本身有开销。轮询CPU不断读DMA的状态寄存器。优点是延迟低且确定。缺点是CPU被占住干不了别的。实时性要求高的场景比如闭环控制轮询更稳吞吐优先的场景中断更合适。混合方案也常见平时用中断关键路径上用轮询。4. DDR缓存架构数据的中转站怎么设计才不堵车4.1 为什么需要DDR而不是全放BRAMFPGA片内的BRAM很快但容量有限。一颗中端FPGA通常只有几MB到几十MB的BRAM。而一帧4K图像就是24MB一段音频采样轻松上百MB。BRAM装不下必须外挂DDR。DDR的特点是容量大GB级别、带宽高几GB/s到几十GB/s、但延迟高几十到上百纳秒。这个高延迟是设计缓存架构时必须时刻记住的。打个比方BRAM像你手边的抽屉伸手就拿到但装不了多少东西DDR像楼下的仓库能装很多但每次去拿都要走一段路。缓存架构的核心就是设计好什么时候去仓库、一次拿多少、怎么减少往返次数。4.2 乒乓缓冲最经典也最实用的架构乒乓缓冲Ping-Pong Buffer是数据流处理里最常用的架构。原理很简单准备两块缓冲区一块在写数据进来一块在读数据出去写满一块就交换角色。时间轴 阶段1: Buffer A 写入 | Buffer B 读出 阶段2: Buffer A 读出 | Buffer B 写入 阶段3: Buffer A 写入 | Buffer B 读出 ...这样做的好处是读写可以并行不会因为写的时候不能读而停顿。代价是需要两倍缓冲空间。在DDR上实现乒乓缓冲关键参数是缓冲区大小。太小了切换频繁开销大太大了延迟高实时性差。经验公式缓冲区大小 数据率 × 单次处理时间 × 安全系数(1.5~2)比如数据率100MB/s单次处理需要10ms那缓冲区至少100MB/s × 0.01s × 1.5 1.5MB。4.3 多级缓存BRAMDDR的组合拳纯DDR方案有个问题DDR延迟高如果每个数据都直接读写DDR效率很低。所以实际项目里通常是多级缓存第一级BRAM小块缓存。用来做突发聚合把零散的小数据攒成一大块再写DDR减少DDR访问次数。第二级DDR大容量缓存。存整帧、整段数据。第三级可选片外大容量存储。用于超大数据集。这个架构的核心思想是用BRAM的快来掩盖DDR的慢。BRAM负责和高速逻辑对接DDR负责存大块数据中间用DMA搬运。4.4 带宽匹配别让某一级成为瓶颈缓存架构设计里最容易翻车的地方是带宽不匹配。举个真实场景采集端AD采样率100MSPS16位数据率200MB/s处理模块能处理300MB/sDDR写入理论800MB/s实际500MB/sDDR读出理论800MB/s实际500MB/s看起来每一级都够用但如果你同时读写DDR乒乓缓冲实际可用带宽要减半变成250MB/s。这时候采集端200MB/s 处理端读200MB/s 400MB/s超过250MB/sDDR成了瓶颈。解决办法提高DDR效率优化突发长度、增加outstanding用更宽的DDR位宽降低数据率比如降采样用多块DDR并行设计阶段一定要画一张带宽流向图把每一级的输入输出带宽标出来找出最窄的那一段。这个习惯能帮你省下大量后期调试时间。5. 从零搭一条数据通路我的实际搭建顺序和踩坑记录5.1 先跑通最小闭环再谈优化我见过太多人一上来就想搭一个完美的、高性能的数据通路结果卡在某个细节上几天出不来。正确的做法是先跑通最小闭环一个数据源可以是简单的计数器或者ROM通过AXIS送到DMADMA写到DDRDMA从DDR读回数据送到一个简单的校验模块比如比对是否一致这个闭环跑通了说明AXI/AXIS握手、DMA配置、DDR访问这条链路是通的。然后再逐步替换成真实的数据源和处理模块。我自己的习惯是先用ILA集成逻辑分析仪抓波形确认握手正常再用软件读DDR确认数据正确最后才上真实数据。每一步都验证出问题容易定位。5.2 握手死锁AXIS最常见的坑AXIS的握手规则看起来简单TVALID和TREADY同时为高时数据传输。但实际写代码时死锁是最常见的坑。典型死锁场景发送方等TREADY才拉高TVALID接收方等TVALID才拉高TREADY。两边互相等永远等不到。正确做法发送方的TVALID一旦有数据就必须拉高不能等TREADY。TREADY由接收方根据自己能不能收来决定。这是AXIS协议的基本规则但新手经常违反。另一个坑是组合逻辑路径TVALID和TREADY如果直接组合相连容易产生长路径时序难收敛。建议在关键路径上加寄存器打拍但要注意打拍会引入延迟需要重新验证握手逻辑。5.3 DDR访问效率突发和bank交错DDR的实际带宽远低于理论值很大原因是访问模式不友好。DDR内部有多个bank每次访问需要先激活行row再读写列column。如果访问地址跳来跳去频繁换行效率极低。提升效率的关键连续访问尽量访问连续地址让DDR能利用突发bank交错把数据分散到不同bank让多个bank并行工作足够深的outstanding让DDR控制器有足够多的请求可以调度在FPGA侧这些通常由DDR控制器IP自动处理但你的访问模式会直接影响效果。写DMA时尽量用大块连续传输避免小碎块。5.4 时序收敛数据通路比算法更难收敛一个容易被忽视的点数据通路的时序往往比算法模块更难收敛。原因是数据通路通常位宽大128位、256位、扇出高、跨时钟域多。我的经验数据通路的关键路径上能打拍就打拍不要吝啬寄存器跨时钟域用异步FIFO不要用简单的双触发器同步数据位宽大时不可靠高位宽数据考虑用流水线拆分组合逻辑时序报告里如果数据通路的WNS最差负裕量是负的优先优化这里而不是算法模块。6. 几个让我印象深刻的真实问题排查过程6.1 数据偶尔错一个缓存一致性的锅有个项目DMA搬运图像数据大部分时候正常但偶尔某一帧会错几个像素。查了很久最后发现是CPU在DMA写完后立即读数据读到了cache里的旧值。排查过程先用ILA抓DMA写DDR的波形数据是对的再用软件读DDR发现偶尔不对。这就锁定了是CPU侧的问题。加上cache invalidate操作后问题消失。教训涉及DMA和CPU共享内存时缓存一致性必须显式处理不能想当然。6.2 带宽上不去outstanding数量不够另一个项目DDR理论带宽3.2GB/s实际只跑到800MB/s。查了访问模式、突发长度都没问题。最后发现是DMA的outstanding数量配置太小DDR控制器没有足够的请求可以调度导致流水线填不满。把outstanding从4增加到16后带宽直接翻倍。这个参数在IP配置里很容易被忽略但对性能影响巨大。6.3 系统偶发卡死AXIS反压处理不当有个系统跑几分钟就卡死一次。用ILA抓波形发现是某个时刻TREADY一直为低TVALID一直为高数据传不过去上游模块的FIFO满了整个链路堵死。根因是下游模块在处理某个特殊数据时处理时间过长导致TREADY长时间为低。上游没有做好反压处理FIFO溢出。解决增加FIFO深度并在上游加入超时机制如果TREADY长时间为低就丢弃或报警。反压是AXIS的正常机制但必须有边界不能无限等待。7. 一些让数据通路更稳的实操习惯做了这么多项目我总结出几个习惯能显著减少数据通路的问题第一永远先画带宽流向图。把每个模块的输入输出带宽标出来找出瓶颈。这个图在项目初期画一次后期能省无数调试时间。第二AXIS握手逻辑单独验证。不要等到整个系统联调才发现握手问题。写个简单的testbench专门测TVALID/TREADY的各种组合包括同时拉高、先后拉高、中途撤销等边界情况。第三DMA配置参数记录在案。outstanding数量、突发长度、描述符对齐要求这些参数一旦确定就记下来换平台或升级IP时对照检查。第四DDR访问尽量大块连续。小碎块访问是DDR效率杀手能合并就合并。第五留足调试接口。ILA的触发条件、状态寄存器、错误计数器这些在调试阶段是救命稻草。宁可多留不要少留。第六缓存一致性方案在架构阶段定死。不要等到出问题再补那时候改动成本极高。数据通路这个东西设计好了是隐形的你感觉不到它的存在设计不好它会用各种奇怪的方式提醒你。Part.23这个阶段其实就是从能跑到跑得稳、跑得快的分水岭。把AXI/AXIS、DMA、DDR缓存这三块吃透后面的项目会顺很多。最后分享一个我自己的小技巧每次搭新数据通路我都会先写一个数据生成器数据校验器的测试框架生成已知模式的数据比如递增序列、伪随机序列经过整条通路后再校验。这个框架搭一次后面所有项目都能复用能快速定位是通路问题还是算法问题。这个投入绝对值得。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询