时序参数全解:洞悉SDIO的tSU、tH、tODLY、tCLK

做SDIO调优,绕不开这几个参数。你去看规范文档,满篇都是tSU、tH、tODLY、tCLK,但到底它们什么意思?取值多少?怎么影响你的板子?今天咱们把这个啃透。

我个人习惯先把协议侧和芯片侧的概念分开。卡有卡的要求,主控有主控的输出。搞混了,调试时就会抓瞎。

1. tSU(Setup Time)——数据必须在时钟前站好

tSU是卡对主控的要求:在时钟采样沿到来之前,CMD/DAT线上的数据必须稳定下来。说白了,数据得提前“就位”。

取值范围呢?我翻了下SDIO 2.0和3.0规范,给你个直觉:

模式 典型tSU(最小值) 备注
Default Speed (0–25 MHz) 5 ns SDIO 2.0 基本要求
High Speed (25–50 MHz) 3 ns 上升沿采样,更紧
UHS‑I SDR12/SDR25 1.6 ns 1.8V 信号,时序更严
UHS‑I SDR50/DDR50 0.8 ns 极限情况,几乎没冗余
经验值:我一般留出 50% 以上的裕量。比如卡要求 5 ns,我至少保证 7.5 ns 的 setup 裕量。别问为什么,问就是温度电压变化会吃掉你的余量。

2. tH(Hold Time)——时钟沿之后别急着变

tH 和 tSU 是孪生兄弟。它要求数据在时钟采样沿之后还要维持一段时间。为什么会这样?因为卡内部触发器需要一点点时间来锁存数据,数据变太快,锁不住。

曾经有个项目,高速读写时随机丢包。我用示波器抓,setup 裕量很大,hold 时间却贴着底线。原来是走线等长没做好,某根数据线比时钟短了太多,导致 hold 违例。嗯,调了走线后问题解决。

典型 tH 取值范围(最小值):

  • Default Speed:2.5 ns
  • High Speed:1.5 ns
  • UHS‑I SDR12/SDR25:0.8 ns
  • UHS‑I SDR50/DDR50:0.4 ns
警惕:有些 FPGA 输出默认 delay 很小,IOB 里不加 delay 元素的话,hold 很容易违例。我曾经因为忘了开 IODELAY,导致三个批次的不良率飙到 15%。

3. tODLY(Output Delay)——卡吐出数据要多久

tODLY 是卡侧的参数:从时钟的有效沿到卡内数据出现在引脚上的时间。主控靠这个来推算采样窗口。

这个参数对主控的 RX 时序设计至关重要。比如卡说 tODLY(max) 是 14 ns,时钟周期 20 ns(50 MHz),那么主控必须在时钟沿之后至少等 14 ns 才能采样,否则可能采到旧数据。

不同速率下的典型 tODLY:

  • Default Speed:tODLY(max) ≈ 14 ns
  • High Speed:tODLY(max) ≈ 7 ns
  • UHS‑I SDR50:tODLY(max) ≈ 1.8 ns
  • UHS‑I DDR50:tODLY(max) ≈ 1.4 ns

数值越来越小,说明卡内部响应更快。但也意味着主控的采样窗口更窄,调起来更费劲。

4. tCLK(时钟周期与频率)——节奏决定一切

tCLK 就是时钟周期,或者倒过来叫时钟频率。SDIO 规范里对 tCLK 有限制:最小周期对应最大频率。但别忘了还有占空比要求,一般45%–55%之间。

取值速查:

模式 最大频率 最小周期 占空比要求
Default Speed 25 MHz 40 ns 40%–60%
High Speed 50 MHz 20 ns 45%–55%
UHS‑I SDR50 100 MHz 10 ns 45%–55%
UHS‑I DDR50 50 MHz (DDR) 20 ns (等效) 45%–55%

我碰过最奇葩的案子:芯片手册写支持50 MHz,但实际波形占空比只有38%。一测,卡直接不响应。调了时钟源的 duty 后恢复正常。所以说,别只盯着频率,占空比也要看。

5. 时序关系一张图

下面这张 SVG 把四个参数的关系画出来了。CLK 作为基准,数据信号上标出 tSU、tH、tODLY 的位置。你琢磨一下:主控发数据要看 tSU、tH(满足卡要求);卡发数据回来,主控要看 tODLY 和 tCLK。

SDIO 时序参数关系图 CLK CMD/DAT tSU tH tODLY tCLK 关键理解 主控 → 卡:需满足 tSU 和 tH(数据在时钟沿前后稳定) 卡 → 主控:需考虑 tODLY 和 tCLK(主控采样窗口 = tCLK − tODLY − 其他损耗) 裕量 = 实际时序 − 最小值,留足余量应对 PVT 变化

6. 实际调优中的经验法则

光知道参数值不够,还得会用。我总结几条实战心得:

  • Always 留余量:tSU/tH 至少多 50%,tODLY 按 max 算。
  • 温度是敌人:高温下 I/O 驱动变弱,setup 会变差。 我在高低温箱里吃过亏——常温跑得好好的,85°C 就随机挂。
  • 走线等长:时钟和数据的走线长度差尽量控制在 5mm 以内,否则 skew 吃掉 tSU 或 tH。
  • 用 delay chain 微调:FPGA 里调用 IDELAY/ODELAY,Software 里调整采样相位,效果立竿见影。
一个小技巧:写个 Python 脚本来验算裕量。
# 计算 setup 裕量(示例)
freq_mhz = 50        # 时钟频率
tclk = 1000 / freq_mhz  # ns
tsu_req = 3.0        # 卡要求 3 ns
tsu_actual = 5.2     # 实际测量或仿真值
setup_margin = tsu_actual - tsu_req
print(f"Setup margin: {setup_margin:.2f} ns")
if setup_margin < 1.5:
    print("⚠️ 裕量偏小,建议优化")

好了,参数全解就聊到这儿。记住:tSU、tH、tODLY、tCLK 这四个数字,是你和 SDIO 卡沟通的密码。下回调时序时,心里先过一遍这张图,多半能少跳几个坑。