DMA与MMIO的读写操作均通过三种基本报文实现:MWr(写请求)、MRd(读请求)和CPLD(完成带数据)。
MMIO的读写机制较为简单:写操作直接发起一次MWr请求;读操作则先发起MRd请求,然后等待一个包含数据的CPLD报文作为响应。
相比之下,DMA的读写行为则复杂得多,但其原理依然可以理解。
Request

Memory请求包在传输时需遵循以下规范
4KB 地址边界限制
Memory 读写请求不允许跨越自然的 4KB 边界。若传输的起始地址与数据长度之和超过一个 4KB 页面(即地址对齐到 0x1000 的整数倍,如 0x1000, 0x2000, 0x3000 等),则必须将该请求拆分为多个不跨越边界的独立操作。
Tag 字段位宽
默认情况下,仅使用 Tag 字段的 [4:0] 位,共支持 32 个唯一标识符。
嗅探属性建议
在大规模数据传输场景下,为提升总线效率,建议将 No Snoop 属性置为 1,即关闭硬件嗅探机制。
Complete

Completion 包用于响应读请求(MRd),其中封装了所请求的读数据。处理 Completion 包时需关注以下要点
RCB(Read Completion Boundary)
RCB 由 Root Complex 读取各 Endpoint 配置空间中的 RCB 参数,并取其中的最小值决定。目前可选值为 64B 或 128B。例如,若 EP0 为 64B,EP1 和 EP2 为 128B,则最终 RCB 为 64B。
数据跨越 RCB 边界的分包规则
-
• 若请求的数据未跨越 RCB 字节整数倍的地址边界,则必须在一个 Completion 包中返回所有数据。
-
• 若请求的数据跨越了 RCB 字节整数倍的地址边界,则允许拆分为多个 Completion 包返回,并遵循:
-
• 第一个包必须从请求的起始地址开始;若状态为 Successful,其结束地址应为下列之一:
-
• 整个请求的结束地址(即仅一个包,也就是说可以一次性发完不需要拆)
-
• 起始与结束地址之间的某个 RCB 对齐边界
-
• 最后一个包(状态为 Successful)必须在整个请求的结束地址处完成
-
• 中间的所有包(状态为 Successful)长度必须为 RCB 的整数倍
分包示例说明
- • 例1:起始地址 0x0000,MPS = 128B,RCB = 64B,长度 = 256B
可不拆分一次性发出
可拆分为两个 128B 的包发送。
- • 例2:起始地址 0x0010,RCB = 64B,长度 = 116B,MPS = 32B分包情况为:0x0010–0x001F → 0x0020–0x003F → 0x0040–0x005F...
在实际设计中,MPS(最大有效载荷大小)通常是RCB的整数倍且大于RCB。因此,在考虑数据分包时,我们只需关注MPS的边界约束即可。

关键字段说明
-
• Length:以 DW(4字节)为单位
-
• Lower Address:在某种意义上等同于 First DW BE,用于指示第一个 DW 中的有效字节数。其 8 位宽度与 RCB(最大128B)相关
-
• Byte Count:以字节为单位,但值为 4 的倍数。当满足
Length × 4 = Byte Count时,表示当前为最后一个包。示例:MPS = 128B,Addr = 0x10,Len = 240B -
• 第一包:Length = 28 DW(112B),Byte Count = 240
-
• 第二包:Length = 32 DW(128B),Byte Count = 128
评论区
登录后即可参与讨论
立即登录