前言
在高性能 PCIe 外设的微架构设计中,数据通路的主控权归属是一个绕不开的系统级考量。主机与 FPGA 之间的数据搬运,通常存在两种截然不同的 DMA 交互模型:Host 端主动发起写请求(Host Push 模式,下发 PCIe MWr 并在 FPGA 侧产生 WREQ),以及 FPGA 端主动发起读请求(FPGA Pull 模式,上发 PCIe MRd 拉取数据)。
实际工程落地中,业界几乎清一色选择 FPGA 作为 Initiator 的 Pull 模式。这一架构倾向并非偶然,而是基于流量控制、系统卸载、状态闭环以及总线吞吐等多个维度的硬核微架构考量共同决定的。下文逐一拆解背后的底层逻辑。
流量控制与端到端反压机制
总线级死锁是系统设计中必须规避的致命风险,而不同的数据交互模式对缓存满溢的处理机制也截然不同。
Host Push (WREQ)
当 Host 直接向 FPGA 发起连续的 AXI WREQ 时,本质上是一种盲推机制。FPGA 侧必须在接收端预留足够深度的 RAM 或 FIFO。若 FPGA 内部后级处理流水线发生拥塞(例如以太网 MAC 侧触发限速,或 DDR 带宽达到瓶颈),接收 FIFO 一旦满溢,前端逻辑只能通过拉低 AXI 的 wready 信号进行硬反压。这种反压向上传导至 PCIe 控制器后,会迅速耗尽链路层的 Credit,最终阻塞整条 PCIe 通道,甚至引发 Host 侧的总线死锁。
FPGA Pull (RREQ)
采用 Pull 模式时,FPGA 拥有数据拉取的绝对主动权。控制逻辑会根据内部接收 Buffer 的当前水位(Watermark)来决定何时发起读请求、以及发起多大 Size 的读请求。这种基于应用层状态的天然流量整形机制,从根本上消除了底层总线的硬反压风险,实现了真正意义上的端到端流量平滑。
描述符解析与硬件卸载逻辑
现代数据中心网络(如智能网卡发包、NVMe-oF 存储协议)中,Host 内存里的数据载荷往往不是物理连续的,而是通过 Scatter-Gather List (SGL) 离散分布,由 Ring Buffer 或 Virtqueue 统一管理。
Push 模式
若采用 Host Push 方案,Host 侧的 DMA 引擎必须轮询队列、解析复杂的 SGL 表单,并向 FPGA 发起海量离散的 WREQ。这会明显消耗 Host 的 CPU 周期与内存带宽,直接违背了硬件卸载 Host 负载的设计初衷。
FPGA 的控制逻辑
行业标准做法是在 FPGA 内部实现完整的 DMA 逻辑(如 vDMA、XDMA 等)。FPGA 作为 Initiator,先通过 MRd 拉取 Descriptor,再在内部 RTL 中解析出各个数据片段的物理地址与 Length,随后并行发起独立的 Read Request 去拉取实际的 Payload。整个控制与调度闭环都在 FPGA 内部完成,对 Host 完全透明,达到了硬件卸载的目的。
事务属性与状态机同步
在 RTL 设计中,状态机(FSM)的严密性依赖确定性的握手信号。PCIe 事务属性的差异,直接影响状态同步的复杂度。
PCIe MWr (Posted)
Host 发起的 MWr(对应 FPGA 的 WREQ)属于 Posted 事务。事务在发起端发送完毕即告结束,Host 侧无需等待 Completion。这意味着 Host 无法精确获知数据何时真正穿过各级 FIFO 落入 FPGA 的处理引擎,系统级的状态同步变得异常困难。
PCIe MRd (Non-Posted)
FPGA 发起的 MRd 属于 Non-Posted 事务。发送请求后,FPGA 会等待 Host 返回 Completion with Data (CplD)。对于 FPGA 侧的控制流而言,携带特定 Tag 的 CplD 报文到达,是一个具备极高确定性的事件。该信号可直接用于触发后级协议解析状态机,使整条硬件流水线的时序逻辑严密可控。
Outstanding 并发与传输延迟
想要在 PCIe Gen4 或 Gen5 链路上跑满峰值有效带宽,必须有效掩盖 Host 侧内存寻址与总线往返的绝对 Latency。
在 Pull 模式下,FPGA 能充分利用 AXI/PCIe 接口的 Outstanding 特性。通过预先发射多个携带不同 Tag 的 Read Request 在总线上排队,FPGA 维持了一个较深的 In-flight 请求池。当 Host 的 CplD 数据报文乱序返回,或被拆分为多个 MPS 边界的短 TLP 到达时,FPGA 内部的 Reorder Buffer 可以依据 Tag 字段进行无缝重组。
写在最后
由数据消费者(FPGA)来主导数据获取的时机、粒度与并发深度,是构建高性能、无阻塞硬件数据通路的唯一解。Host Push 仅适用于低频的 CSR 配置下发,对于海量高频数据流,FPGA Pull 模式在架构上具有不可替代的优越性。这类底层数据通路话题在 云栈社区 也常被拿出来反复讨论,感兴趣的朋友可以一起参与交流。