信号完整性基础:时钟域交叉、建立时间与保持时间

Write Leveling 的本质是什么?说白了就是让 DQS 和 CK 对齐。但别急着调延时,你得先搞清楚两个最基本的时序概念——建立时间和保持时间。我见过不少工程师,上来就改寄存器,结果越调越乱。嗯,我们先停一下,把这块地基打牢。

3.1 时钟域交叉——跨域信号怎么“过河”

DDR 系统里,控制器和 DRAM 各自有独立的时钟域。控制器发 DQS,颗粒用 CK 采样。这两个时钟可能同频、可能不同频,相位更是随 PCB 走线和温度飘移。这就是典型的时钟域交叉(Clock Domain Crossing,CDC)问题。

数据从一个时钟域跳到另一个时钟域时,最怕什么?亚稳态——采样时刻刚好落在数据变化窗口里,输出既不是 0 也不是 1。我曾经在一个 DDR3 项目里,颗粒偶尔读错数据,查了三天发现是 CK 和 DQS 的相位差刚好卡在建立/保持窗口边界上,换了片 FPGA 就好了。这个问题非常隐蔽。

关键点:Write Leveling 的实质,就是通过调整 DQS 相对 CK 的延时,让 DQS 的上升沿落在 CK 的建立+保持时间窗口中心。不是随便对齐,而是要留足裕量。

跨时钟域同步的经典方式是两级触发器同步。但 DDR 的 DQS 是源同步时钟,不靠触发器打拍——它直接用 DQS 的边沿去采样 CK。所以 Write Leveling 绕不开建立/保持时间的物理约束。

3.2 建立时间 vs 保持时间——一枚硬币的两面

建立时间(tSU)要求数据在时钟沿来临前必须稳定。保持时间(tHD)要求数据在时钟沿之后还要保持稳定。你想想看,数据从变到稳,有一个过渡区——这个区域里谁都不敢采样。

我习惯用一个生活比喻:你约了朋友在车站碰面,建立时间就是他必须提前 5 分钟到站台(数据提前稳定),保持时间就是车开走后他还要在原地站 2 分钟(数据保持稳定)。如果朋友刚好在车到站那秒才到,你俩就可能错过(亚稳态)。

参数 含义 典型值(DDR4 3200) 违反后果
建立时间 tSU 时钟沿前数据必须有效的最小时间 200~300 ps 接收数据出错,产生亚稳态
保持时间 tHD 时钟沿后数据必须保持有效的最小时间 200~300 ps 采样到错误逻辑,导致位翻转

在 Write Leveling 场景中,DRAM 的 CK 是采样时钟,DQS 是数据(写时 DQS 作为 strobe 随数据一起发)。DQS 的边沿必须同时满足 CK 的 tSU 和 tHD。如果 DQS 比 CK 早太多,可能破坏保持时间;晚太多,建立时间不够。

我曾经踩过的坑:某 DDR4 板卡,Write Leveling 训练总是报失败。查了很久,发现 PCB 上 CK 走线长了 200 ps,导致 DQS 相对 CK 自然提前。我们只调了控制器的延时,没考虑走线偏差,结果建立时间被吞掉。后来改用 tDQSCK 补偿才搞定。

3.3 时序窗口——你的裕量有多大

数据稳定的总窗口 = 时钟周期 - (tSU + tHD)。这个窗口就是所谓的“眼睛”。窗口越大,系统越稳健。DDR 频率越高,窗口越窄——DDR5 的窗口已经窄到 100 ps 量级。

计算实际裕量时,要考虑以下因素:

  • DQS 相对于 CK 的初始相位(即 Write Leveling 要调整的目标)
  • PVT 变化(工艺、电压、温度)带来的漂移
  • PCB 走线差异(等长匹配只能做到 ±10 ps)
  • 接收端 DQS 时钟域内部的 gate 延迟

我建议你调试时,先把 tSU 和 tHD 的规格书值记下来,然后用示波器看 DQS 相对于 CK 的边沿位置——别光靠软件报告。我曾经在实验室里,软件显示“通过”,示波器一看已经贴在窗口边缘了。

小技巧:用 BIET(Built-in Eye Test)功能扫描 DQS 延时,找到失效边界。取中间值作为最终设置——这就是所谓的“最佳眼图中心”。

3.4 知识图谱——本章核心结构

下面这张图把时钟域交叉、建立时间和保持时间的关系串起来。你看一眼就知道他们在 Write Leveling 里扮演什么角色。

时钟域交叉与建立/保持时间关系图 发送时钟域 CLK_A DQS 产生 (源同步时钟) 接收时钟域 CLK_B CK 采样 (DRAM 端) 数据/时钟跨域 建立时间 tSU 窗口 保持时间 tHD 窗口 CK 采样边沿 Write Leveling 目标: DQS 边沿落入 tSU 和 tHD 之间 亚稳态风险: 边沿落在禁止区内 → 采样错误

3.5 实践中的建立/保持时间调试

调试时,我一般走三步:

  1. 确认时钟关系——用示波器看 CK 和 DQS 的相位差,记录初始偏移。
  2. 扫描训练——用 FPGA/控制器自带的细粒度延时步进,从最小到最大遍历,记录每个步进下的训练结果(pass/fail)。
  3. 取中点——找到两个失效边界(建立失效边界和保持失效边界),取它们的中点作为最终延时值。

这个流程看起来简单,但有个细节容易被忽略:温度对走线延迟的影响。我曾经在环境箱里做 HTOL 测试,室温下训练好的值,85°C 时就挂了。后来我把延时设置从边界中点偏外 10% 留了余量,才通过所有温度点。

记住:建立时间和保持时间不是孤立存在的。它们通过 Write Leveling 的延时调整互相制约。你动一个,另一个的裕量就变。一定要看全窗口,别只盯着一个方向。