3. Zynq DDR控制器架构解析
Zynq-7000 的 DDR 存储子系统并不是一个简单的“内存接口”,而是由 DDR 控制器(DDRC/DDRMC)、AXI 互联、调度器、地址映射逻辑以及物理层(PHY)共同组成的完整数据通路。理解这套架构,是后续做时序约束、带宽评估和稳定性验证的基础。本节围绕控制器内部结构、AXI 接口、调度策略、地址映射以及 Bank/Row/Column 管理机制展开。
一、控制器在系统中的位置与整体结构
在 Zynq-7000 中,DDR 控制器通常被称为 DDRC(DDR Controller),在部分文档和工具中也被称为 DDRMC(DDR Memory Controller)。它位于 PS(Processing System)内部,一端通过 AXI 接口连接中央互联(Central Interconnect),另一端连接 DDR PHY,再由 PHY 驱动片外 DDR 颗粒。整体上可以划分为三个层次:
- AXI 接口层:接收来自 CPU、DMA、PL 等主设备的读写请求,完成协议转换与请求排队。
- 控制器核心层:包含命令调度器、地址映射单元、Bank/Row/Column 管理、刷新与初始化控制。
- PHY 与颗粒层:完成 DDR 时序训练、DQS/DQ 对齐,并最终访问 DDR 芯片。
控制器核心层是本节的重点。它内部维护多个请求队列,将 AXI 事务拆解为对 DDR 颗粒的 ACT(激活)、RD/WR(读写)、PRE(预充电)、REF(刷新)等命令,并按调度策略决定命令发出的顺序。
二、AXI 接口层:请求如何进入控制器
Zynq 的 DDR 控制器对外呈现为 AXI 从设备,通常挂接在中央互联的某个端口上。CPU、DMA、PL 等主设备发出的读写请求,经过互联仲裁后到达 AXI 接口层。这一层主要完成三件事:
- 协议转换:将 AXI 的突发传输(Burst)拆解为控制器内部可识别的内存事务。例如 AXI 的 INCR 突发长度为 8、位宽 64 bit,会被拆成若干个与 DDR 突发长度匹配的访问单元。
- 请求排队:读写请求分别进入读队列和写队列。控制器支持多个 Outstanding 事务,队列深度决定了能同时“在途”的请求数量,直接影响带宽利用率。
- QoS 与优先级:不同主设备可携带 QoS 标记,调度器据此决定先服务谁。例如 CPU 的实时性要求高,DMA 的大块传输则更看重吞吐。
需要特别注意的是,AXI 接口层并不直接产生 DDR 命令,它只负责把请求整理成控制器核心层能消费的形式。真正的“什么时候发 ACT、什么时候发 RD”由调度器决定。
三、调度策略:从请求队列到 DDR 命令
DDR 颗粒的物理特性决定了不能随意访问任意地址:同一 Bank 内换行需要先预充电再激活,跨 Bank 访问则可以交错进行以隐藏延迟。调度器的核心任务就是在满足时序约束的前提下,尽可能提高总线利用率。
常见的调度策略包括:
- 先来先服务(FCFS):实现简单,但容易因行冲突导致频繁 PRE/ACT,效率低。
- 行命中优先(Row Hit First):优先服务与当前已激活行相同的请求,减少 PRE/ACT 开销。这是最常用的基础策略。
- Bank 交错与分组:将请求按 Bank 分组,在多个 Bank 之间轮转,利用 tFAW、tRRD 等约束的间隙插入其他 Bank 的命令。
- 读写切换优化:DDR 总线读写切换需要额外的周转周期(tWTR、tRTW),调度器会尽量批量处理同向请求,减少切换次数。
在 Zynq 中,这些策略由控制器硬件自动执行,用户能干预的主要是 QoS 配置和部分时序参数。理解调度逻辑的意义在于:当带宽不达预期时,可以判断是行冲突过多、读写频繁切换,还是 Outstanding 不足。
四、地址映射:AXI 地址如何变成 Bank/Row/Column
控制器内部有一个地址映射单元,负责把 AXI 字节地址翻译成 DDR 颗粒的 Bank、Row、Column 以及 Burst 内偏移。映射方式直接决定了访问模式是否容易产生行命中。
以一颗 16 bit 位宽、8 Bank、Row 地址 15 位、Column 地址 10 位的 DDR3 颗粒为例,一种常见的映射关系是:
| 地址位段 | 对应字段 | 说明 |
|---|---|---|
| [2:0] | Burst 内偏移 | 决定 8 拍突发的字节位置 |
| [12:3] | Column[9:0] | 列地址,决定页内位置 |
| [15:13] | Bank[2:0] | 8 个 Bank 选择 |
| [30:16] | Row[14:0] | 行地址,决定激活哪一行 |
这种“低位 Column、中位 Bank、高位 Row”的排列,使得连续的大块访问会先在同一行内递增 Column,再切换 Bank,最后才换 Row。对于顺序访问,行命中率很高;对于跨步较大的访问,则容易频繁换行。
五、Bank/Row/Column 管理机制
DDR 颗粒内部是一个二维阵列:每个 Bank 有若干 Row,每行有若干 Column。访问一个位置的标准流程是:
ACT(Row, Bank) → 激活目标行,将整行读入行缓冲
RD/WR(Col) → 在已激活行内读写指定列
PRE(Bank) → 预充电,关闭当前行
ACT(下一行) → 激活新行
控制器内部为每个 Bank 维护一个状态机,记录该 Bank 当前是“空闲”“已激活”还是“正在预充电”。当新请求到达时,调度器会检查目标 Bank 的状态:
- 如果目标行已经激活,直接发 RD/WR,称为行命中,延迟最低。
- 如果 Bank 已激活但行不同,需要先 PRE 再 ACT,称为行冲突,延迟显著增加。
- 如果 Bank 空闲,直接 ACT 即可。
此外,控制器还必须周期性插入刷新命令(REF),因为 DDR 电容会漏电。刷新会占用总线时间,且与正常访问争抢资源。Zynq 控制器会根据温度和工作模式自动调整刷新间隔,用户一般无需手动干预,但在高负载场景下刷新开销是带宽评估中不可忽略的一部分。
综上,Zynq DDR 控制器是一个“AXI 接口 + 调度器 + 地址映射 + Bank 状态管理 + PHY”的协同系统。AXI 层负责接收和整理请求,调度器负责在时序约束下重排序,地址映射决定访问模式,Bank/Row/Column 管理则直接决定行命中率和实际带宽。后续做 DDR 配置与验证时,这些内部机制就是判断“为什么带宽上不去”“为什么延迟波动大”的根本依据。