PCIe 6.0 协议标准最终版正式公布了,其中的技术细节也没必要藏着掖着了,之前写的协议分析笔记终于可以分享出来了。官方宣传媒体图,上!
1. L0p基本介绍
1.1 L0p引入
PCIe 5.0中低功耗状态有:L0s,L1、动态链路宽度切换、速度切换。L0p是PCIe 6.0新引入的一种低功耗状态,工作在L0p状态下PCIe设备可以在不中断数据发送的情况下完成链路宽度切换,从而提升链路的带宽利用率、降低功耗。
L0p在LTSSM中的位置如图1所示,其不是LTSSM主状态之一,某种意义上讲,L0p是L0的一部分。
▲ 图1 L0p在LTSSM中的位置
1.2 L0p的目的意义
L0p的目的意义大致有以下几点:
- Flit Mode只支持L0p。PCIe 6.0工作在Flit Mode时不支持L0s,转而采用L0p。
- 采用L0p时,不中断数据传输即可实现链路宽度切换。非Flit Mode下,或没有L0p时,调整链路宽度需要LTSSM从L0 -> Recovery -> Configuration,此间几us内数据流被中断。
- L0p下被关掉的lane的功耗与L0s几无差别,这样一来,既能保证链路的带宽率利用率,也能链路降低功耗。
- 上调链路宽度从L0p回退到L0时,PHY无需重新训练。
1.3 L0p的适用范围
L0p适用于工作在Flit Mode的PCIe设备,是一项可选的功能,PCIe设备可以通过设备控制寄存器3的L0p Enable位(图2)来决定是否开始L0p功能。对于采用PCIe 6.0的Retimer,其伪端口必须支持L0p。
L0p只适用于Flit Mode,但其并非只适用于PCIe 6.0。采用了PCIe 6.0 IP的设备,若其工作在Gen1~Gen5速率下且为Flit Mode,L0p对其仍然适用。反过来讲, 采用了PCIe 6.0 IP的设备,若其工作在Flit Mode下,即便其速率为Gen1~Gen5的速率,其仍然不能进入L0s的低功耗状态。
▲ 图2 Device Control 3 Register
1.4 L0p能力协商
收发端通过交换TS序列协商该链路是否启用L0p能力。TS1或TS2序列(standard或modified)中的数据速率指示符号第0bit(即symbol 4 bit 0) 指示当前设备其是否支持L0p,收发端在Configuration.Complete状态形成最终决定,L0p能够动态切换最大链路宽度是在Configuration.Linkwidth.Accept状态决定的。
Flit Mode不等于L0p,因为L0p是可选的功能。即便工作在Flit Mode下,若设备未实现或未使能L0p能力,则设备仍然不能进入L0p状态,也不能动态调整链路宽度,此时调整链路宽度仍然需要从 L0 -> Recovery -> Configuration。
2. L0p的进入和退出
2.1 L0p动态链路宽度调整
2.1.1 策略概述
一般而言,Flit Mode的PCIe设备在初次training的时默认开启全部可用的lane。在工作过程中,根据带宽利用情况决定下调或扩展lane的数目。进入L0状态后,初次发送L0p请求一定是链路宽度下调。
链路宽度下调:当吞吐量较小链路较清闲时,收发端协商后进入L0p状态降低活跃态的lane数目。在保证现有数据发送带宽需求的前提下,关闭部分lane使其进入电气闲状态,同时剩余lane继续发送数据流。
链路宽度上调:链路宽度上调的前提是当前链路已经工作在L0p状态且lane数目未达到最大。若当前PCIe设备吞吐量逐渐加大以至于目前lane数难以满足需求,收发端协商上调lane数目,激活电气闲状态的lane,以满足系统吞吐量需求。
注意:
在协商好的最大链路宽度范围内,L0p支持的动态切换链路宽度为x1, x2, x4, x8, x16。L0p不支持到x1, x3, x5等的切换。
鉴于Configuration状态时关闭的lane存在链路可靠性差的可能,L0p不能也无法激活在Configuration状态下关闭的lane。如果需要激活其他lane,仍然需要L0 -> Recovery -> Configuration重新协商。
从L0p -> Recovery后,有效链路宽度回退到进L0p之前L0的链路宽度。
若链路控制寄存器(图3)中的自动链路关闭位置一,则 ①禁止发送链路宽度下调的L0p请求,且 ②必须发送上调链路宽度的请求,将链路宽度恢复至最近一次Configuration协商后的最大链路宽度。
▲ 图3 Link Control Register
2.1.2 L0p响应ACK和NAK规则
USP或DSP均可以主动发起动态切换链路宽度请求,另一方可以同意(回ACK)也可以拒绝请求(回NAK)。只有在双方就能不能进L0p、切换成哪种链路宽度达成一致之后,才能进入预期的L0p链路状态。Rx在收到L0p请求后,必须在1us内进行回应;若请求者在2us内未等到回应,其可以重新发送请求,也可以放弃请求。
更多L0p ACK和NAK规则如下:
若L0p.Priority为0,不论当前端口是否已处于L0p,其均有权拒绝对端发来的链路宽度下调L0p请求。
若端口出于热节流或链路可靠性原因请求下调链路宽度,其应将L0p 请求中的L0p.Priority位置一,并确保在100ns内开始发送该L0p请求。此时,若对端未发送L0p请求且下个Flit也不打算发送L0p请求,那么对端必须接受该L0p请求并回复ACK。
任何请求动态下调链路宽度的端口,即便其得到了对端的ACK答复,当导致其链路宽度下调的因素消除后,其应主动恢复原有的链路宽度。
若DSP和USP同时请求L0p动态链路切换(某端口收到L0p请求后100ns内自己也会发送L0p请求即为同时),此时双方需要竞争方能成为最终的requester。竞争规则如下:
○ 若双方L0p.Priority均置一,链路宽度窄者胜;
○ 若只有一方L0p.Priority置一,L0.Priority置一者胜;
○ 若双方L0p.Priority均为0,L0p请求链路宽度不同链路宽者胜,链路宽度相同DSP胜。
2.1.3 L0p动态链路宽度调整举例
以X16链路为例,一种L0p动态切换链路宽度的协商过程如图4所示:
- DSP与USP在Configuration状态协商开启L0p能力。
- USP发送L0p请求给DSP,请求将链路宽度切换为x8,DSP回复ACK。
- DSP即USP lane 0-7继续传输数据流,lane 8~15 发送EIOSQ并进入电气闲状态。
- 一段时间后,DSP发送L0p请求,请求上调链路宽度为x16,同时USP请求继续把链路宽度下调至x4。两者L0p.Priority均为0,DSP获胜,USP回复x16 L0p以ACK,DSP回复x4 L0p以NAK。
- lane 8~15 重新发送TS1或TS2以重新训练,并在合适位置插入EIEOS使链路退出电气闲。
DSP及USP均工作在x16下。
▲ 图4 L0p动态链路宽度举例
2.1.4 链路宽度下调
双方端口就链路宽度下调达成一致意见后,两方端口需要独立完成以下事项:
- 待关闭lane上从其下一Flit开始将Flit中的SKPOS替换为EIOSQ,发送完EIOSQ后进入电气闲状态,其他无需关闭的lane不发送EIOSQ,且照常发送数据Flit。
- 若发出L0p请求的端口未收到ACK,只要其收到了EIOSQ,等同于收到ACK,该关lane的关lane。
- 所有待关闭的lane上同时收到EIOS后才能进入L0p,若存在某待关闭的lane上未收到EIOS,则不能进入L0p,而是进入Recovery。
2.1.5 链路宽度上调
双方端口就链路宽度上调达成一致意见后,需要完成以下事项:
- 发送L0p请求的端口在待开启的lane上发送EIEOSQ,其他lane照常发送数据流,对端收到EIEOSQ后激活相关lane。
- 在开启相关lane时,需注意:待开启的lane与其他正常工作中的lane一起规划SKPOS。考虑到待开启的lane在发送EIEOSQ中的多个EIEOS时有可能会被SKPOS打断,此时可以通过合理规划EIOSQ的起始时刻来保证其中的多个EIEOS背对背发送(未被SKPOS打断),一旦被SKPOS打断,可以重新发。
- 所有待开启的lane上均连续收到8个TS1或TS2后,开始发送TS2。
- 数据速率为8GT/s及以上时,若所有待激活的lane上收到8个连续的TS2,且在收到1个TS2后发出了16个TS2,该端口所有激活及待激活状态下的lane在发送下一SKPOS前需发送SDS。
- 数据速率为8GT/s及以上时,Rx需在所有已激活、待激活的lane间完成lane间de-skew。
- 若24ms还没激活相关lane,则进入Recovery状态。