【笔记】PCIe LTSSM 状态转移

简介: 【笔记】PCIe LTSSM 状态转移

1. LTSSM 状态转移图


1.1 主状态跳转图

14318be589f5483aac8cb5a8e9c16c73.png


▲图 1 LTSSM 主状态跳转



1.2 子状态跳转图


1.2.1 子状态跳转总图

417c097f98664235961176d29041e11a.png


▲图 2 LTSSM 子状态跳转  (图片绘制 DOT 代码见附件 A)




1.2.2 Detect 子状态跳转


3e88a56bc6f54ee792419318e5f0080e.png



▲图 3 Detect 子状态转移

1.2.3 Polling 子状态跳转

2cf541688c7f4c2ba67b1a0452bd3a11.png


▲图 4 Polling 子状态转移

1.2.4 Configuration 子状态跳转

c36dfff19d254c2e804c7048cf16ebec.png

▲图 5 Configuration 子状态转移

1.2.5 Recovery 子状态跳转

08388d9d7c8145848f450daed973e4d4.png


▲图 6 Recovery 子状态转移


注: Loopback.Entry <-> Recovery.Equalization 存在,未体现在该图中。



1.2.6 L0s 子状态跳转

348f89964c3f4856967bd26aaa84d63d.png


▲图 7 L0s 子状态转移

1.2.7 L1 子状态跳转

345e00e9e18941c5ba75e356860144da.png


▲图 8 L1 子状态转移

1.2.8 L2 子状态跳转

ec3ceec890ee43149f220e08045804c8.png


▲图 9 L2 子状态转移

1.2.9 Loopback 子状态跳转

593c06bbaf7748768df1802bc8bb0bd3.png


▲图 10 Loopback 子状态转移

1.2.10 L0 不含子状态


1.2.11 Disable 不含子状态

1.2.12 Hot Reset 不含子状态



2. 完整的状态跳转


2.1 从初始状态到指定速率

2.1.1 Init -> Gen1


Detect.Quiet -> Detect.Active -> Polling.Active -> Polling.Config -> Config.LinkwidthStart -> Config.LinkwidthAccept -> Config.LanenumWait -> Config.LanenumAccept -> Config.Complete -> Config.Idle -> Gen1 L0



2.1.2 Init -> Gen2

Gen1 L0 -> Recovery.RcvrLock -> Recovery.RcvyCfg -> Recovery.Speed -> Recovery.RcvrLock -> Recovery.RcvyCfg -> Recovery.Idle -> Gen2 L0



2.1.3 Init -> Gen3


Full equalization


Detect.Quiet -> ... -> Gen1 L0 -> Recovery.RcvrLock -> Recovery.RcvyCfg -> Recovery.Speed -> Recovery.RcvrLock -> Recovery.Eq -> Recovery.RcvrLock -> Recovery.RcvyCfg -> Recovery.Idle -> Gen3 L0


注:Init -> Gen3 可拆分为 Init -> Gen1 ` -> Gen3,为节省篇幅,对 Init -> Gen1 详细过程进行了省略,详情请参考上文。



Bypass equlization to highest rate


Detect.Quiet -> ... -> Gen1 L0 -> Recovery.RcvrLock -> Recovery.RcvyCfg -> Recovery.Speed -> Recovery.RcvrLock -> Recovery.RcvyCfg -> Recovery.Idle -> Gen3 L0


No equlization needed


Detect.Quiet -> ... -> Gen1 L0 -> Recovery.RcvrLock -> Recovery.RcvyCfg -> Recovery.Speed -> Recovery.RcvrLock -> Recovery.RcvyCfg -> Recovery.Idle -> Gen3 L0


2.1.4 Init -> Gen4


Full equalization


Detect.Quiet -> ... -> Gen3 L0 -> Recovery.RcvrLock -> Recovery.RcvyCfg -> Recovery.Speed -> Recovery.RcvrLock -> Recovery.Eq -> Recovery.RcvrLock -> Recovery.RcvyCfg -> Recovery.Idle -> Gen4 L0


注:Init -> Gen4 可拆分为 Init -> Gen1 -> Gen3 -> Gen4,为节省篇幅,对 Init -> Gen1 -> Gen3 过程进行了省略,详情请参考上文。


Bypass equlization to highest rate


Detect.Quiet -> ... -> Gen1 L0 -> Recovery.RcvrLock -> Recovery.RcvyCfg -> Recovery.Speed -> Recovery.RcvrLock -> Recovery.RcvyCfg -> Recovery.Idle -> Gen4 L0

No equlization needed

Detect.Quiet -> ... -> Gen1 L0 -> Recovery.RcvrLock -> Recovery.RcvyCfg -> Recovery.Speed -> Recovery.RcvrLock -> Recovery.RcvyCfg -> Recovery.Idle -> Gen4 L0



2.1.5 Init -> Gen5


Full equalization


Detect.Quiet -> ... -> Gen4 L0 -> Recovery.RcvrLock -> Recovery.RcvyCfg -> Recovery.Speed -> Recovery.RcvrLock -> Recovery.Eq -> Recovery.RcvrLock -> Recovery.RcvyCfg -> Recovery.Idle -> Gen5 L0


注:Init -> Gen5 可拆分为 Init -> Gen1 -> Gen3 -> Gen4 -> Gen5,为节省篇幅,对 Init -> Gen1 -> Gen3 -> Gen4 过程进行了省略,详情请参考上文。


Bypass equlization to highest rate

Detect.Quiet -> ... -> Gen1 L0 -> Recovery.RcvrLock -> Recovery.RcvyCfg -> Recovery.Speed -> Recovery.RcvrLock -> Recovery.Eq -> Recovery.RcvrLock -> Recovery.RcvyCfg -> Recovery.Idle -> Gen5 L0


No equlization needed


Detect.Quiet -> ... -> Gen1 L0 -> Recovery.RcvrLock -> Recovery.RcvyCfg -> Recovery.Speed -> Recovery.RcvrLock -> Recovery.RcvyCfg -> Recovery.Idle -> Gen5 L0



2.2 从某速率切速到指定速率


2.2.1 Gen1/2 -> Gen1/2

Gen1/2 L0 -> Recovery.RcvrLock -> Recovery.RcvyCfg -> Recovery.Speed -> Recovery.RcvrLock -> Recovery.RcvyCfg -> Recovery.Idle -> Gen1/2 L0

2.2.2 Gen1/2 -> Gen3/4/5


Full Equalization


不管之前是否曾经到过做高速率,从当前速率开始,经过 EQ 先跳转到 Gen3 L0,再到 Gen4 L0,然后到 Gen5 L0,一路跳到目标速率。可参考上文。


No equalization needed


Gen1/2/ L0 -> Recovery.RcvrLock -> Recovery.RcvyCfg -> Recovery.Speed -> Recovery.RcvrLock -> Recovery.RcvyCfg -> Recovery.Idle -> Gen3/4/5 L0

2.2.3 Gen3/4/5 -> Gen1/2


Gen3/4/5 L0 -> Recovery.RcvrLock -> Recovery.RcvyCfg -> Recovery.Speed -> Recovery.RcvrLock -> Recovery.RcvyCfg -> Recovery.Idle -> Gen1/2 L0

2.2.4 Gen3/4/5 -> Gen3/4/5


Full Equalization


相邻两种速率间切速,例如 Gen3 < -> Gen4,Gen4 <-> Gen5,过一遍 EQ 直接切速:


GenA L0 -> Recovery.RcvrLock -> Recovery.RcvyCfg -> Recovery.Speed -> Recovery.RcvrLock -> Recovery.Eq -> Recovery.RcvrLock -> Recovery.RcvyCfg -> Recovery.Idle -> GenB L0


Gen3 -> Gen5,中间需要先切速到 Gen4,然后切速到 Gen5:


Gen3 L0 -> Recovery.RcvrLock -> Recovery.RcvyCfg -> Recovery.Speed -> Recovery.RcvrLock -> Recovery.Eq -> Recovery.RcvrLock -> Recovery.RcvyCfg -> Recovery.Idle -> Gen4 L0 -> Recovery.RcvrLock -> Recovery.RcvyCfg -> Recovery.Speed -> Recovery.RcvrLock -> Recovery.Eq -> Recovery.RcvrLock -> Recovery.RcvyCfg -> Recovery.Idle -> Gen5 L0


Gen5 -> Gen3,过一遍 EQ 直接切速:


Gen5 L0 -> Recovery.RcvrLock -> Recovery.RcvyCfg -> Recovery.Speed -> Recovery.RcvrLock -> Recovery.Eq -> Recovery.RcvrLock -> Recovery.RcvyCfg -> Recovery.Idle -> Gen3 L0


注: 以上为仿真观察到的现象,具体得看下 Spec 怎么讲的。


No equalization needed


Gen3/4/5 L0 -> Recovery.RcvrLock -> Recovery.RcvyCfg -> Recovery.Speed -> Recovery.RcvrLock -> Recovery.RcvyCfg -> Recovery.Idle -> Gen3/4/5 L0




3. 实战笔记



3.1 SNPS PCIe 5.0 LTSSM 状态码


▼表 1 SNPS PCIe 5.0 LTSSM 状态码

f384c45453d34a6dbdfc683e773e26e7.png




4. 附录


A. DOT 画 LTSSM 子状态转移 代码


        # https://hifpga.com/fsm/
        #状态机示例
        digraph ltssm {
        "Reset" -> "Detect.Quiet"
                // Detect
        //subgraph cluster_detect {
            label="Detect"
            "Detect.Quiet" [color=greenyellow; style=filled; fontcolor=black]
            "Detect.Active" [color=greenyellow; style=filled; fontcolor=black]
            "Detect.Quiet" -> "Detect.Active"
            "Detect.Active" -> "Detect.Quiet"
        //}
        "Detect.Active" -> "Polling.Active"
        // Polling
        //subgraph cluster_polling {
            label="Polling"
            "Polling.Active" [color=gold; style=filled; fontcolor=black]
            "Polling.Compliance" [color=gold; style=filled; fontcolor=black]
            "Polling.Configuration" [color=gold; style=filled; fontcolor=black]
            //"Polling.Speed" [color=gold; style=filled; fontcolor=black]
        //}
        "Polling.Active" -> "Polling.Configuration"
        "Polling.Active" -> "Polling.Compliance"
        "Polling.Active" -> "Detect.Quiet"
        "Polling.Compliance" -> "Polling.Active"
        //"Polling.Configuration" -> "Polling.Speed"
        "Polling.Configuration" -> "Detect.Quiet"
        "Polling.Configuration" -> "Config.RcvrCfg"
        //"Polling.Speed" -> "Polling.Active"
        // Configuration
        //subgraph cluster_configuration {
            label="Configuration"
            "Config.RcvrCfg" [color=plum; style=filled; fontcolor=black]
            "Config.Idle" [color=plum; style=filled; fontcolor=black]
        //}
        "Config.RcvrCfg" -> "Config.Idle"
        "Config.RcvrCfg" -> "Detect.Quiet"
        "Config.RcvrCfg" -> "Disable"
        "Config.RcvrCfg" -> "Loopback.Entry"
        "Config.Idle" -> "Detect.Quiet"
        "Config.Idle" -> "L0"
        // L0
        "L0" [color=pink; style=filled; fontcolor=black]
        "L0" -> "Recovery.RcvrLock"
        "L0" -> "Tx_L0s.Entry"
        "L0" -> "Rx_L0s.Entry"
        // L0s
        //subgraph cluster_L0s {
            label="L0s"
            "Tx_L0s.Entry" [color=orange; style=filled; fontcolor=black]
            "Tx_L0s.Idle" [color=orange; style=filled; fontcolor=black]
            "Tx_L0s.FTS" [color=orange; style=filled; fontcolor=black]
            "Rx_L0s.Entry" [color=lightblue; style=filled; fontcolor=black]
            "Rx_L0s.Idle" [color=lightblue; style=filled; fontcolor=black]
            "Rx_L0s.FTS" [color=lightblue; style=filled; fontcolor=black]
        //}
        //"L0" -> "Tx_L0s.Entry" [lhead=cluster_L0s]
        //"L0" -> "Rx_L0s.Entry" [lhead=cluster_L0s]
        // L0s_Tx
        "Tx_L0s.Entry" -> "Tx_L0s.Idle"
        "Tx_L0s.Idle" -> "Tx_L0s.FTS"
        "Tx_L0s.FTS" -> "L0"
        // L0s_Rx
        "Rx_L0s.Entry" -> "Rx_L0s.Idle"
        "Rx_L0s.Idle" -> "Rx_L0s.FTS"
        "Rx_L0s.FTS" -> "L0"
        "Rx_L0s.FTS" -> "Recovery.RcvrLock"
        // L1
        //subgraph cluster_L1 {
            label="L1"
            "L1.Entry" [color=salmon; style=filled; fontcolor=black]
            "L1.Idle" [color=salmon; style=filled; fontcolor=black]
        //}
        "L0" -> "L1.Entry"
        "L1.Entry" -> "L1.Idle"
        "L1.Idle" -> "Recovery.RcvrLock"
        // L2
        //subgraph cluster_L2 {
            Label="L2"
         "L2.TransmitWake" [color=springgreen; style=filled; fontcolor=black]
         "L2.Idle" [color=springgreen; style=filled; fontcolor=black]
        //}
        "L0" -> "L2.Idle"
        "L2.Idle" -> "L2.TransmitWake"
        "L2.TransmitWake" -> "Detect.Quiet"  
        // Recovery
        //subgraph cluster_recovery{
            label="Recovery"
            "Recovery.RcvrLock" [color=khaki; style=filled; fontcolor=black]
            "Recovery.RcvrCfg" [color=khaki; style=filled; fontcolor=black]
            "Recovery.Idle" [color=khaki; style=filled; fontcolor=black]
            "Recovery.Equalization" [color=khaki; style=filled; fontcolor=black]
            "Recovery.Speed"  [color=khaki; style=filled; fontcolor=black]
        //}
        "Recovery.RcvrLock" -> "Detect.Quiet"
        "Recovery.RcvrLock" -> "Config.RcvrCfg"
        "Recovery.RcvrLock" -> "Recovery.RcvrCfg"
        "Recovery.RcvrLock" -> "Recovery.Equalization"
        "Recovery.RcvrLock" -> "Recovery.Speed"
        "Recovery.Speed" -> "Recovery.RcvrLock"
        "Recovery.Speed" -> "Detect.Quiet"
        "Recovery.Equalization" -> "Recovery.RcvrLock"
        "Recovery.Equalization" -> "Recovery.Speed"
        "Recovery.RcvrCfg" -> "Recovery.Speed"
        "Recovery.RcvrCfg" -> "Recovery.Idle"
        "Recovery.RcvrCfg" -> "Config.RcvrCfg"
        "Recovery.RcvrCfg" -> "Detect.Quiet"
        "Recovery.Idle" -> "Loopback.Entry"
        "Recovery.Idle" -> "Disable"
        "Recovery.Idle" -> "L0"
        "Recovery.Idle" -> "Hot Reset"
        "Recovery.Idle" -> "Config.RcvrCfg"
        // Loopback
        //subgraph cluster_loopback {
            label="Loopback"
            "Loopback.Entry" [color=mistyrose; style=filled; fontcolor=black]
            "Loopback.Active" [color=mistyrose; style=filled; fontcolor=black]
            "Loopback.Exit" [color=mistyrose; style=filled; fontcolor=black]
        //}
        "Loopback.Entry" -> "Loopback.Active"
        "Loopback.Entry" -> "Loopback.Exit"
        "Loopback.Active" -> "Loopback.Exit"
        "Loopback.Exit" -> "Detect.Quiet"
        // Hot Reset
        "Hot Reset" [color=red; style=filled; fontcolor=black]
        "Hot Reset" -> "Detect.Quiet"
        // Disable
        "Disable" [color=grey; style=filled; fontcolor=black]
        "Disable" -> "Detect.Quiet"
        }



参考


  1. PCI Express Base Spec 5.0, 6.0


  1. Mindshare PCI Express Technology



目录
相关文章
|
缓存 异构计算 Perl
【毅力挑战】PCIe 每日一问一答(2022.04 归档)
【毅力挑战】PCIe 每日一问一答(2022.04 归档)
3929 3
【毅力挑战】PCIe 每日一问一答(2022.04 归档)
|
异构计算
PCIe链路训练(Link Training) Debug案例解析
有关Xilin FPGA开发版PCIe link up issue debug过程的文章,小编把里面提到的一个案例在这里给大家分享一下。
|
缓存 移动开发 JavaScript
PCIe 参考时钟架构 (Refclk Architecture)
PCIe 参考时钟架构 (Refclk Architecture)
6627 0
PCIe 参考时钟架构 (Refclk Architecture)
|
存储
PCIe VPD (Vital Product Data) 介绍
PCIe VPD (Vital Product Data) 介绍
4040 0
PCIe VPD (Vital Product Data) 介绍
【PCIe 协议】听说你做 PCIe 很多年,还不知道 PCIe Hierarchy ID 是什么 ???
【PCIe 协议】听说你做 PCIe 很多年,还不知道 PCIe Hierarchy ID 是什么 ???
1095 0
【PCIe 协议】听说你做 PCIe 很多年,还不知道 PCIe Hierarchy ID 是什么 ???
|
算法
PCIe 均衡技术介绍(逻辑物理篇)2
PCIe 均衡技术介绍(逻辑物理篇)
5285 1
PCIe 均衡技术介绍(逻辑物理篇)2
|
芯片
PCIe 均衡技术介绍(电气物理篇)
PCIe 均衡技术介绍(电气物理篇)
9409 0
PCIe 均衡技术介绍(电气物理篇)
浅析PCIe链路LTSSM状态机
我们知道,在PCIe链路可以正常工作之前,需要对PCIe链路进行链路训练,在这个过程中,就会用LTSSM状态机。LTSSM全称是Link Training and Status State Machine。这个状态机在哪里呢?
PCIe 均衡技术介绍(逻辑物理篇)
PCIe 均衡技术介绍(逻辑物理篇)
3758 0
PCIe 均衡技术介绍(逻辑物理篇)
|
存储 IDE 开发工具
【毅力挑战】PCIe 每日一问一答(2022.02 归档)
【毅力挑战】PCIe 每日一问一答(2022.02 归档)
5120 1
【毅力挑战】PCIe 每日一问一答(2022.02 归档)

热门文章

最新文章