基于FPGA实现PCIe H2C过程中TAG的一种管理方法

基于FPGA实现PCIe H2C过程中TAG的一种管理方法

PCIe DMA · Tag 管理 · 顺序队列 · 纯 RTL 实现

一、背景

在基于 Xilinx 7 系列 PCIe 硬核做 DMA 传输时,H2C(Host to Card,主机到板卡)方向本质上是一连串存储器读请求:板卡上的 DMA 引擎向主机发出读请求,主机通过**带数据的完成包(CplD)**把数据送回来。

PCIe 协议规定,每个读请求必须携带一个 Tag ,主机的完成包会原封不动地把这个 Tag 带回来,发送端正是靠它来区分"这包数据是哪个请求的响应"。协议同时规定:同一个 Tag 必须等它的完成包全部返回后才能复用。也就是说,Tag 是一种"借出---归还"型的有限资源。

一个 DMA 系统往往不只有一个数据流。以本文讨论的设计为例,H2C 方向同时存在四类请求源:

  1. 数据通道的正常 DMA 读;
  2. 描述符预取通道的读;
  3. SGL 链表(散列-聚集列表)的读取;
  4. C2H 方向列表信息的读取。

这些通道共享同一个 PCIe IP 的请求接口,也就共享同一个 Tag 空间。若没有统一管理,会出现两类致命问题:

  • Tag 冲突:两个通道拿到同一个 Tag 发请求,完成数据回来后无法归属;
  • 数据错路由:完成包回来时,不知道该送到哪个用户通道,也不知道该有多长。

因此需要一个集中式的 TAG 管理模块,完成申请、登记、路由、释放四件事。本文介绍一种基于"环形指针 + 顺序释放 + 并行匹配"的实现方法。

二、总体思路

核心思想一句话概括:

把 32 个 Tag 当作一个环形缓冲区来用------申请时顺序发放,释放时也必须按申请顺序释放。

这样做的依据来自 PCIe 协议本身:

  • 读请求按序发出后,完成包的返回顺序与请求顺序一致(同一流量类别下,后发的读请求,其完成包不会越过先发的);
  • 每个请求占用一个 Tag,其完成包结束后该 Tag 即可回收。

既然"借出顺序"和"归还顺序"天然一致,就不需要为每个 Tag 维护集中式查找表,只需两个指针:写指针 指向下一个待发放的 Tag,读指针 指向最早发出、等待归还的 Tag。两者之间夹着的,就是全部"在途"请求。

三、申请侧:仲裁与发放

3.1 请求仲裁

四个请求源可能同时发起 Tag 申请。设计采用轮询仲裁:

  • 只有一个请求源在申请时,直接放行,不浪费节拍;
  • 多个请求源同时申请时,按一个循环移位的优先级序列依次裁决,保证各通道长期获得均等机会,避免高吞吐通道"饿死"其他通道。

一轮仲裁完成后,胜出的通道拿到授权,进入发放流程。

3.2 Tag 发放与信息登记

发放动作由写指针完成:

  • 当前写指针的值就是要发放的 Tag ID,直接回给胜出的请求源,后者随即带着这个 Tag 组装读请求;
  • 与此同时,把本次请求的三个关键属性写入 TAG 属性存储 (深度 32,位置即 Tag 编号):总长度 (以双字为单位)、是否为最后一个包 的标志、来源通道号------数据最终送回哪个用户通道,全靠它。

发放之后写指针加一,回到环形下一位。

3.3 流量控制

Tag 是有限资源(本设计为 32 个,与 PCIe 典型的在途请求配额匹配)。用申请计数减去释放计数得到当前在途数量,并衍生出四种状态:

状态 含义 用途
空 在途数为 0 系统空闲指示
将空 在途数 ≤ 1 预警
将满 在途数 ≥ 31 提前反压,留余量给流水线
满 在途数为 32 硬反压,拒绝一切新申请

"将满"阈值比"满"提前一拍,是给仲裁和发放流水线留出反应时间------若等到满才反压,已进入发放流水线的请求会造成 Tag 超发。

四、完成接收侧(上):并行匹配与私有缓存

完成数据从 PCIe 硬核返回时携带 Tag 编号,且数据流是"广播"性质------任何一个在途请求的数据都可能出现在其中。如何把广播数据流准确分发到 32 个在途请求?本设计没有采用"先解码、再查表、后路由"的集中式方案,而是反过来:为每个 Tag 配一个独立的控制器,让广播数据流同时到达所有控制器,由各控制器自行比对编号------编号命中且本 Tag 处于占用状态的那一个接收数据,其余 31 个视而不见。

这是典型的"以面积换简单性":

  • 匹配逻辑从 1 份变成 32 份,但每份只是一个等值比较;
  • 每个 Tag 拥有一条私有数据缓存,彻底消除多请求争用同一缓存的冲突;
  • 32 份控制器结构完全相同,仅编号参数不同,代码高度规整,时序收敛容易。

为驱动 32 份逻辑,广播数据流、属性写入、读指针三组输入各自复制出多组寄存器副本,以降低扇出、改善时序------这是 FPGA 工程中大扇出信号的标准处理手法。

单个 Tag 控制器内部完成四件事:

  1. 登记:属性写入且地址命中自己的编号时,锁定本次传输的长度、包尾标志和来源通道号,同时置起占用标志;
  2. 匹配接收:监视广播数据流,编号命中且占用时,将数据压入私有 FIFO。由于字节有效以字节为单位而长度以双字为单位,每 4 位取 1 位折算出每拍的双字数并累加;
  3. 收齐上报:累计双字数达到登记长度时,发出"收齐"脉冲------注意此时数据只是收进了私有 FIFO,还没有交给用户;
  4. 按需排空:上层读指针指向自己且下游就绪时,从私有 FIFO 读出数据,一边读一边对剩余长度递减计数,并按剩余长度重组每拍的字节有效与包尾标志;剩余长度减到最后一拍时,发出"排空完成"脉冲------这才是 Tag 真正释放的时刻。

五、完成接收侧(下):按序汇聚与 Tag 释放

32 个控制器的输出汇聚回一条数据流:用读指针做 32 选 1 ,任何时刻只放行"最早在途"的那个 Tag 的私有 FIFO------即便后面的 Tag 早已收齐数据在排队,也必须等它前面的依次排空。这一步把 PCIe 返回数据重整为严格按申请顺序的数据流,四个用户通道看到的顺序从此有了保证。

32 个"收齐"脉冲经两级或树(8→4→1,打两拍)合并成一个"读请求完成"信号,通知上游某次读事务结束;"排空完成"则驱动上层做三件事:在途计数减一、读指针加一、产生通道完成脉冲。接收节奏由主机决定、用户通道各自的就绪状态相互独立,因此数据面统一经过输出 FIFO 缓冲后再按属性中的来源通道号分发,管理逻辑只关心顺序和计数,数据面只关心握手。

六、设计要点与取舍

1. 为什么敢用"顺序释放"?

这是整个方案成立的前提。PCIe 规范保证读完成按请求顺序返回,只要 DMA 引擎按序发请求(本设计中请求经统一仲裁后串行发出,天然有序),完成顺序就有保障。省掉按 Tag 索引的集中式随机查找,用两个指针加一个计数器就完成全部管理,资源开销极小。

2. 属性随 Tag 走,而不是随数据走。

请求发出后,长度、包尾、通道号这些信息就"挂"在 Tag 上了。本设计把属性表展开成 32 份"活动"的控制器:登记、匹配、缓存合为一体,读指针推进到哪,数据与属性就从哪份控制器中取出。比在每个完成包上粘贴旁路元数据稳健得多。

3. "收齐"与"排空"双脉冲分离。

"收齐"是事务级事件,通知 DMA 引擎本次读请求的数据已全部返回;"排空"是数据级事件,代表数据已按序转交、Tag 可回收。两者分离让接收与转发彻底解耦:主机可以尽快归还完成包、腾出 PCIe 流水线,而数据可以按用户侧的节奏慢慢消费。

4. 水线反压是稳定性的关键。

32 个 Tag 一旦超发,会出现两个请求共用一个 Tag 的灾难场景。将满/将空两级水线让上下游都能提前减速,实测中可以把 Tag 用满而不错发。

5. 可扩展性。

将来若增加新的请求源(比如更多 DMA 通道),只需扩展仲裁器的输入位宽和属性中的通道号字段;Tag 深度变化也只是复制更多相同结构的控制器,环形管理的骨架完全不用动。

七、结语

PCIe DMA 中的 Tag 管理,本质上是一个资源分配 + 顺序队列问题。利用 PCIe 读完成天然有序的特性,把 32 个 Tag 组织成"写指针发放、读指针回收"的环形结构;完成侧用 32 份并行匹配的单 Tag 控制器替代集中查表,私有缓存消除冲突,读指针汇聚强制按序,收齐/排空双脉冲解耦接收与转发。整套方法不依赖专用 IP,纯 RTL 即可实现,用很小的资源代价同时支撑多个并发 DMA 通道的正确性与高吞吐,适合作为自研 DMA 引擎中请求管理子系统的参考骨架。

相关推荐
威嵌神州2 小时前
一台加固平板,能替掉几台现场设备?
嵌入式硬件·fpga开发·电脑·平板
幻智星科技15 小时前
树形架构破解FPGA扇出瓶颈
fpga开发·硬件架构
FPGA小迷弟18 小时前
FPGA开发Vivado Block Design/Vitis/SDK/xlinx/开发教程,保姆级别,一看就会!
网络协议·tcp/ip·fpga开发·verilog·fpga
FPGA小迷弟19 小时前
基于FPGA实现智能网卡的概念,什么是智能网卡
网络协议·tcp/ip·fpga开发·verilog·fpga
好焊孙辉21 小时前
螺柱焊机哪家质量好
python·fpga开发
XMAIPC_Robot1 天前
基于 i.MX95 平台在新一代工业控制器中的应用 — 工业车载平板、半导体设备主控方案解析
arm开发·人工智能·机器学习·fpga开发·rk3588+fpga·i.mx95
szxinmai主板定制专家1 天前
基于 AM62x + Artix-7 的低功耗 ARM+FPGA 平台在轨道交通车门控制中的应用
arm开发·人工智能·fpga开发·zynq·am62x
幻智星科技1 天前
我砍掉了FPGA里的ARM核项目反而提前交付了
arm开发·网络协议·fpga开发·硬件架构
逐光者9331 天前
Verilog 三段式状态机:原理、模板与实战
fpga开发