DDR控制器与PHY架构简介
做DDR时序参数设置,首先得把硬件架构看清楚。说白了,你调的那些参数最终要送到两个地方:一个是控制器,一个是PHY。这两者怎么分工?怎么协同?搞明白这些,后面读时序表才不会晕。
我刚开始接触DDR时,以为控制器就是控制读写,PHY就是管信号。实际上一拆开,每个模块都有自己的“脾气”。今天咱们就先把这两层剥开看看。
控制器在做什么?
DDR控制器,你可以把它理解成DDR颗粒的“大脑”。它不负责发模拟信号,而是负责翻译——把CPU或SoC发过来的读写请求,翻译成DDR颗粒能理解的命令和数据顺序。
核心职责:
- 调度读写命令(Page Policy、Bank Management)
- 生成时序约束(比如tRCD、tRP、tCL这些参数)
- 处理刷新、预充电、自刷新等维护操作
- 做地址映射(比如行地址、列地址、Bank地址)
- 管理数据总线方向切换(写转读、读转写)
我个人习惯把控制器分成两大块:命令调度器和数据通路。
- 命令调度器:决定什么时候发ACT、什么时候发READ/WRITE。我在一个项目里遇到过调度器没处理好Bank冲突,导致实测带宽损失了20%。
- 数据通路:负责写数据发送和读数据接收,包括数据掩码(DQM)、数据选通(DQS)的时序对齐。
你可能会问,“那控制器的时钟是谁给的?”一般都是参考时钟(Ref Clk),然后控制器内部做分频或倍频,产生内部工作时钟。这个时钟域和PHY的时钟域之间,需要做跨时钟域处理——嗯,这里水很深,后面会专门讲。
PHY层到底长什么样?
PHY是物理层,它直接和DDR颗粒的管脚打交道。控制器的命令和数据到了PHY这里,要转换成差分的DDR信号,还要做阻抗匹配、延迟校准、ODT控制……
我记得第一次看PHY的框图时,被一堆“DLL”、“ZQ Cal”、“Delay Line”搞晕了。后来才明白,PHY的核心就是解决“什么时候发、发多强、收多准”这三个问题。
几点心得:
- DLL(延迟锁定环):负责将内部时钟与DQS对齐。比如说你的控制器内部是800MHz,DLL要产生一个精确的90°相移来对准读DQS。
- 读写延时调整:每个字节通道都有独立的可编程延时单元,用来补偿PCB走线延迟差异。我有个项目因为CLK到DQS的走线差了200ps,读训练一直不过,加了一级延时就好了。
- ODT控制:动态调整片上端接电阻,减少信号反射。这个参数如果在软件里设错了,DDR根本跑不到标称频率。
另外,PHY还包含训练逻辑——上电后要自动做写均衡、读均衡、ZQ校准、Vref调优。这些训练结果会直接反映在一堆寄存器里,也就是我们要去读的那些“training status”。
控制器与PHY的接口——DFI协议
把控制器和PHY连起来的那个标准接口叫DFI(DDR PHY Interface)。现在主流版本是DFI 5.x,支持DDR5/LPDDR5。
DFI协议定义了哪些信号?我列个简表:
| 信号方向 | 信号名称 | 说明 |
|---|---|---|
| 控制器→PHY | dfi_address, dfi_bank | 地址和Bank控制 |
| 控制器→PHY | dfi_cs_n, dfi_cke, dfi_odt | 片选、时钟使能、ODT |
| 控制器→PHY | dfi_wrdata, dfi_wrdata_mask | 写数据和掩码 |
| PHY→控制器 | dfi_rddata, dfi_rddata_valid | 读数据及有效标志 |
| 双向 | dfi_phy_master, dfi_phy_error | 控制与状态反馈 |
这里有个关键点:DFI本身也是有时序规范的。比如从控制器发出命令到PHY真正驱动管脚,之间有固定的延时(通常叫“dfi_tphy_wrlat”)。我们在调整时序参数时,需要把这些PHY内部的流水线延时也算进去。
注意: 很多SoC的DDR控制器手册里给的时序参数是“控制器侧”的,实际加在颗粒上的时刻要加上PHY的延迟。如果你只看颗粒的数据手册调参数,又只看控制器的寄存器描述,中间很容易漏掉几周期。我曾经吃过这个亏,写DDR3训练时读回来的数据总是错位,最后发现是PHY侧插入的延迟没考虑。
架构总览:一张图看清
下面这张SVG图把控制器、DFI、PHY以及DDR颗粒的关系画了出来。建议你保存下来,后面的章节会反复参考这几个模块。
理解分层:从SoC到颗粒
整个DDR接口可以抽象成三层:
- 交易层(Transaction Layer):由控制器实现,处理命令队列、Bank管理。你设置的tFAW、tRRD这些参数主要影响这一层。
- 链路层(Link Layer):由DFI接口承载,负责协议打包、ECC、CRC(DDR5支持)。
- 物理层(Physical Layer):PHY和DDR IO Buffer负责信号完整性。Vref、ODT、delay校准都在这一层。
为什么要这样分?我的理解是:每一层关注不同的时间尺度。交易层关注ns级时序(比如ACT到READ的延迟),物理层关注ps级抖动和眼图。你做时序参数设置时,其实是在同时调整这两层——既要满足颗粒的tRCD/tCL等宏观约束,又要让DLL锁定在正确的相移上。
实战建议: 如果你使用的是供应商提供的控制器+PHY IP,一定要拿到完整的集成指南。里面通常会有一张表格,把控制器的寄存器参数和PHY的延迟参数对应起来。比如“tCTRL_RCD”这一步对应PHY侧要加几个流水节拍——这些信息在颗粒数据手册里是找不到的。
嗯,第二章就到这。整体架构理解了,后面再谈具体的“tRCD怎么配”、“tWTR为什么必须大于某个值”,你就知道这些参数在哪个模块生效了。