目录
简介:
最近项目中,遇到了一个一个问题,就是DDR初始化失败,失败卡在write leveling。
名词解释:
MC(Memory Controller)不断地调整DQS-DQS#信号相对于CK-CK#的延迟,颗粒端在每个DQS-DQS#上升沿采样CK-CK#信号。若采样值为低,则将所有DQ[n]保持为低来告知MC,tDQSS相位关系还未满足;若在某个DQS-DQS#上升沿采样到CK-CK#电平发生跳变(如0-->1),则认为此时tDQSS已满足。则将所有DQ[n]保持为高(异步反馈)来告知MC,tDQSS相位关系已满足,表征写均衡成功,同时DDR控制器会锁住这个相位差。
为什么需要:
显然,在 fly-by 结构中,命令地址信号到达每个 DRAM 的时间有很大不同。但是数据到达每个 DRAM 的时间却是接近的,这会导致每个 DRAM 时钟信号(随命令地址总线传输)和数据的偏差不一致。
从原理上说,对于单个 DRAM 时钟与其数据之间的偏差,这些偏差一般为固定的走线偏差,控制器采用调整时钟或者数据的延迟链来补偿偏差。
但对于多个 DRAM 芯片组成的系统而言,调整单个 DRAM 是不够的。由于每个 DRAM 的时钟-数据偏差不同,而且控制器还不知道具体每个 DRAM 的偏差是多大!这样一来,控制器就无法在整个 DIMM 内存条(DRAM 系统)层面上保持 tDQSS,tDSS,tDSH 等时序参数。
如下图所示,两个 DRAM 的数据信号几乎同时到达,但时钟信号有一定的偏差,即使在调整 DRAM0 的 DQS 信号的延迟,使 DRAM 0 可以完成数据采样后,DRAM 1 仍然无法完成采样。
为了克服时钟与数据之间的偏差在每个 DRAM 颗粒上的不确定性,DRAM 需要进行 write leveling ,针对每个 DRAM 芯片量身训练一个时钟与数据之间的偏差补偿。时钟选取 CK 信号本身,而数据则选取 DQS 信号来表示,DQS 是数据有效信号,这里暂且认为其与真正的数据信号 DQ 是完全同步的。
所以 write leveling 会针对每个 DRAM 芯片,进行 CK 与 DQS 信号间的相位调整,采用一种多次试错,寻找最优值的方法使 DRAM 接收到的时钟信号与写数据同步。
这里强调 write leveling 是一项每个 DRAM 芯片层面上的训练项目,是因为还有其他训练项目会对 DRAM 芯片内部的不同组成部分进行训练。不过严格来说 write leveling 是针对每个 lane 进行训练的,这里简单起见,选用 x8 DRAM 作为例子,一个 DRAM 芯片只对应于一个 lane。如果是 x16 的颗粒,那么其 2 个 byte lane 需要分别训练。
关键时序:
tDQSS,tDSS,tDSH
tDQSS 是 DQS 上升沿相对 CK 上升沿的偏差
tDSS,tDSH 分别是 DQS 信号下降沿相对于 CK 上升沿的建立和保持时间。建立或者保持时间的违例会导致 DQS 采样失败。一般来说,当 tDQSS 调整到位时,这两者也就一起到位了,无需特别的调整。
可以不要吗
完全可以,如果 DRAM 颗粒的类型、信号线的长度、DRAM 颗粒间的拓扑关系都是固定的,那么控制器使用提前设定的参数,即可以保持 tDQSS,tDSS,tDSH 等时序参数,无需 write leveling。