第2章:DDR协议基础与Exynos实现
2.1 从协议到硬件:一个老工程师的视角
说实话,很多做嵌入式开发的朋友,一看到DDR协议就头疼。
一堆时序参数,什么tRCD、tCL、tWR,看着像天书。我当年刚入行时也一样,觉得这东西离我太远。直到有一次,我调试一个Exynos平台的视频播放卡顿问题,折腾了两周,最后发现是内存控制器的一个时序配置没对齐——嗯,从那以后,我再也不敢小看这些参数了。
说白了,DDR协议就是内存颗粒和控制器之间的“握手规则”。你遵守了,数据就稳稳当当;你偷懒了,系统就给你颜色看。
2.2 关键时序参数:不只是数字
咱们先过一遍最核心的几个参数。我习惯把它们分成三类:行访问类、列访问类和写恢复类。
2.2.1 tRCD(RAS to CAS Delay)
这个参数,我愿称之为“行到列的等待”。
你想想看,内存颗粒内部是个矩阵。你要读数据,得先激活一行(RAS),再选中一列(CAS)。tRCD就是这两步之间的最短时间。
在Exynos内存控制器里,tRCD的配置直接影响随机访问性能。我个人习惯在调优时,先看颗粒的datasheet,找到最小tRCD值,然后往上加1-2个时钟周期作为安全余量。
避坑指南: 我曾经在一个项目中,为了追求极致性能,把tRCD压到了datasheet的极限值。结果高温测试时,内存访问频繁出错。后来发现,Exynos控制器的内部走线延迟比预想的大,必须留够余量。
2.2.2 tCL(CAS Latency)
tCL,也叫读延迟。这是从你发出读命令,到数据第一次出现在数据总线上的时钟周期数。
DDR4时代,tCL通常是10-16个周期。到了DDR5,起步就是28-40个周期。为什么变大了?因为频率上去了,内部流水线更深了。
Exynos控制器对tCL的处理很有意思。它内部有一个自适应延迟调整模块,可以根据当前温度和工作频率,动态微调tCL。我建议你在做功耗优化时,可以适当放宽tCL,换取更低的电压。
| 协议 | 典型tCL范围 | Exynos默认配置 |
|---|---|---|
| DDR4 | 10-16 | 14 |
| DDR5 | 28-40 | 34 |
| LPDDR4x | 10-20 | 16 |
| LPDDR5 | 24-36 | 30 |
2.2.3 tWR(Write Recovery Time)
写恢复时间,这个参数容易被忽略。它指的是最后一次写入数据之后,到发出预充电命令之前,必须等待的时间。
为什么需要这个?因为写入的数据需要时间稳定下来,内部电荷需要时间建立。你想想看,如果刚写完就立刻去关闭这一行,数据可能还没写进去。
Exynos控制器在处理tWR时,有一个写后自动预充电功能。我个人习惯把这个功能打开,尤其是在高负载写入场景下,能有效避免数据丢失。
小技巧: 在Exynos的寄存器配置中,tWR的单位通常是时钟周期。但注意,有些LPDDR5颗粒要求tWR以nS为单位。我曾经踩过这个坑,配置时忘了换算,结果写入性能直接腰斩。
2.3 Exynos如何实现这些协议?
好了,参数讲完了。咱们来看看Exynos内存控制器内部是怎么干活的。
2.3.1 协议引擎:硬件状态机
Exynos内部有一个专门的DDR协议引擎,说白了就是一个复杂的硬件状态机。它负责把CPU发来的内存请求,翻译成DDR颗粒能理解的命令序列。
举个例子,一个读请求进来,状态机会自动执行:
1. 发送ACTIVATE命令(激活行)
2. 等待tRCD个周期
3. 发送READ命令(选中列)
4. 等待tCL个周期
5. 从DQ总线上读取数据
6. 发送PRECHARGE命令(关闭行)
7. 等待tRP个周期
你看,这些时序参数,在Exynos控制器里就是状态机跳转的“等待计数器”。
2.3.2 时序参数寄存器
Exynos把所有的时序参数都映射到了寄存器空间。我常用的几个寄存器地址如下:
| 寄存器名称 | 偏移地址 | 控制的参数 |
|---|---|---|
| DMC_TIMING_A | 0x1000_0000 | tRCD, tRP, tRAS |
| DMC_TIMING_B | 0x1000_0004 | tCL, tCWL, tWR |
| DMC_TIMING_C | 0x1000_0008 | tRFC, tREFI |
调优时,直接修改这些寄存器的值就行。但注意,修改后要执行一次时序重训练,否则新配置不会生效。
2.3.3 自适应校准机制
Exynos有一个很聪明的设计——写均衡(Write Leveling)和读均衡(Read Leveling)。这两个机制会在系统启动时,自动校准时钟和数据的相位关系。
为什么会需要这个?因为DDR频率越来越高,信号在PCB上的飞行时间已经不能忽略了。Exynos通过内部延迟锁相环(DLL),动态调整每个字节通道的延迟。
注意: 如果你在调试中发现内存偶尔出错,先别急着怀疑颗粒。很可能是Exynos的校准机制没跑通。我建议你在启动日志里检查一下“DMC Calibration Done”这个标志位。
2.4 实战:配置一个LPDDR5时序
最后,咱们来点实际的。假设你手头有一块Exynos 2200的板子,配的是LPDDR5-6400颗粒。怎么配置时序?
我一般按这个步骤来:
- 查datasheet:找到颗粒的时序参数表,记下最小值。
- 换算成时钟周期:LPDDR5-6400的时钟频率是3200MHz,周期约0.3125nS。tCL=30,意味着30个周期,约9.375nS。
- 写入寄存器:把换算后的值写入DMC_TIMING_B。
- 触发重训练:设置DMC_SW_TRAINING寄存器为1。
- 验证稳定性:跑一遍内存压力测试,比如memtester。
嗯,这里要注意:LPDDR5的tRFC(刷新周期)特别大,通常是DDR4的两倍。如果你发现内存带宽上不去,先检查tRFC是不是设得太保守了。
好了,这一章就到这里。下一章咱们聊聊Exynos的多通道交织技术,那才是真正榨干内存性能的关键。