3. L1状态详解:低功耗待机模式下的时钟与电源管理机制
L1状态是PCIe链路在无数据流量时进入的低功耗待机模式。与L0s的快速唤醒不同,L1状态通过关闭发送器和接收器的大部分时钟树以及降低主电源电压,实现更显著的功耗节省。进入L1状态需要链路两端(Upstream Port与Downstream Port)通过链路训练状态机(LTSSM)协商一致,并完成特定的电气进入序列。
3.1 L1状态的电源与时钟域划分
在L1状态下,链路物理层被划分为两个主要的电源域:主电源域(Vmain)和辅助电源域(Vaux)。时钟管理则分为参考时钟(Refclk)的保持与PLL的关闭。
| 资源类型 | L0状态 | L1状态 | 说明 |
|---|---|---|---|
| 主电源 (Vmain) | 开启 | 关闭或降至保持电压 | 为TX/RX模拟前端、PLL、数据通路供电 |
| 辅助电源 (Vaux) | 开启 | 开启 | 为唤醒逻辑、寄存器、边带信号供电 |
| 参考时钟 (Refclk) | 稳定运行 | 可保持或关闭 (CLKREQ#) | 由CLKREQ#信号控制,支持时钟暂停 |
| PLL (锁相环) | 锁定 | 关闭或旁路 | 关闭以节省功耗,恢复时需重新锁定 |
| 接收器检测电路 | 不工作 | 周期性工作 | 用于检测对端是否退出L1 |
关键概念: L1状态下的功耗节省主要来源于关闭高速串行收发器(SerDes)和PLL。Vaux电源域必须始终保持供电,以确保链路能够响应来自对端或软件触发的唤醒事件。
3.2 L1状态进入与退出的电气序列
LTSSM从L0状态迁移到L1状态,需要经过一个明确的握手过程,称为“L1 Entry Handshake”。该过程通过物理层发送特定的有序集(Ordered Set)来实现。
3.2.1 L1 Entry 流程
- 发起请求: 链路一端(通常是Downstream Port)发送 PM_Enter_L1 数据链路层报文(DLLP)。
- 确认响应: 对端(Upstream Port)收到后,回复 PM_Request_Ack DLLP。
- 电气空闲: 双方在发送完Ack后,将TX驱动置于电气空闲(Electrical Idle)状态,并停止发送数据。
- 时钟暂停: 如果支持CLKREQ#机制,Downstream Port可以拉高CLKRE#信号,允许参考时钟停止。
- 电源关闭: 链路两端关闭主电源域中的高速电路。
时序要点: 从发送PM_Enter_L1到进入电气空闲,协议要求必须在 2µs 内完成。这是L1状态机切换延迟的关键组成部分。
3.2.2 L1 Exit 流程
- 唤醒触发: 任意一端通过发送 PM_Wake DLLP 或通过边带信号 WAKE# 发起唤醒。
- 时钟恢复: 如果参考时钟已暂停,Downstream Port必须拉低CLKREQ#信号,等待Refclk稳定(通常需要几百纳秒到几微秒)。
- 接收器检测: 唤醒发起端开始发送 TS1 Ordered Set,对端通过接收器检测电路感知到信号变化。
- PLL重新锁定: 双方PLL重新锁定到参考时钟,恢复位对齐和符号对齐。
- 链路训练: 链路进入 Recovery 状态,进行速度协商和链路宽度确认,最终回到L0。
设计挑战: L1 Exit延迟的主要瓶颈在于PLL的重新锁定时间(通常为几微秒)和参考时钟的稳定时间。系统设计时必须确保唤醒时序满足PCIe Base Spec中规定的 Twake 和 Tready 参数。
3.3 L1状态下的时钟管理机制:CLKREQ#
CLKREQ#(Clock Request)是一个可选的边带信号,用于实现更精细的时钟管理。在L1状态下,如果所有设备都不需要参考时钟,Downstream Port可以拉高CLKREQ#,通知时钟源(如Clock Buffer)停止输出Refclk,从而进一步降低系统功耗。
// CLKREQ# 信号时序示例(伪代码描述)
// 假设 Downstream Port 为 Root Complex,Upstream Port 为 Endpoint
// 1. 进入 L1 后,Endpoint 准备暂停时钟
if (LTSSM == L1) {
// Endpoint 拉高 CLKREQ#,表示不再需要 Refclk
CLKREQ#_ENDPOINT = HIGH;
}
// 2. 时钟源检测到所有 CLKREQ# 均为 HIGH,停止 Refclk
if (CLKREQ#_RC == HIGH && CLKREQ#_ENDPOINT == HIGH) {
Refclk_Output = OFF;
}
// 3. 唤醒事件发生,Endpoint 需要时钟
if (WAKE#_asserted || PM_Wake_received) {
// Endpoint 拉低 CLKREQ#,请求 Refclk
CLKREQ#_ENDPOINT = LOW;
// 等待 Refclk 稳定 (T_clk_stable)
wait(T_clk_stable);
// 开始发送 TS1,进入 Recovery
}
3.4 L1状态切换时序参数汇总
以下表格列出了与L1状态切换相关的关键时序参数,这些参数直接影响系统级的电源管理策略和延迟预算。
| 参数符号 | 参数名称 | 典型值 | 说明 |
|---|---|---|---|
| TL1_entry | L1进入延迟 | ~2 µs | 从发送PM_Enter_L1到电气空闲 |
| TL1_exit_wake | L1唤醒延迟 | ~5 µs - 20 µs | 从唤醒触发到开始发送TS1 |
| Tclk_stable | 时钟稳定时间 | ~1 µs - 5 µs | CLKREQ#拉低后Refclk稳定所需时间 |
| Tpll_lock | PLL锁定时间 | ~2 µs - 10 µs | PLL从关闭到锁定所需时间 |
| Trecovery | Recovery状态时间 | ~1 µs - 5 µs | 链路训练恢复时间 |
系统级影响: 从L0到L1再回到L0的总延迟(TL1_entry + TL1_exit_wake + Trecovery)通常在10µs到40µs之间。对于延迟敏感的应用(如NVMe SSD),过长的L1 Exit延迟可能导致性能下降,因此需要权衡功耗与性能。
3.5 L1状态机切换流程图
下图展示了LTSSM在L0、L1以及中间过渡状态之间的切换路径,重点标注了时钟与电源管理的关键动作。
3.6 L1与L0s的对比分析
理解L1与L0s的差异对于设计合理的电源管理策略至关重要。下表从多个维度对比了这两种低功耗状态。
| 对比维度 | L0s | L1 |
|---|---|---|
| 功耗节省 | 中等(仅关闭TX) | 高(关闭TX/RX/PLL/主电源) |
| 进入延迟 | ~几百纳秒 | ~2微秒 |
| 退出延迟 | ~几百纳秒 | ~5-20微秒 |
| 时钟管理 | Refclk保持运行 | Refclk可暂停(CLKREQ#) |
| PLL状态 | 保持锁定 | 关闭,需重新锁定 |
| 适用场景 | 短时间空闲(如DMA间隙) | 长时间空闲(如ASPM L1) |
| 协议协商 | 单端决定,无需握手 | 需要DLLP握手确认 |
设计建议: 对于频繁、短促的空闲周期,优先使用L0s以避免L1 Exit带来的长延迟惩罚。对于预测性较长的空闲(如CPU进入C-state),应使用L1以获得最大的功耗收益。现代PCIe控制器通常支持硬件自动选择(ASPM),根据空闲计数器动态切换。