【笔记】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



目录
相关文章
|
11月前
|
算法 异构计算
m基于FPGA的costas环载波同步verilog实现,包含testbench,可以修改频偏大小
m基于FPGA的costas环载波同步verilog实现,包含testbench,可以修改频偏大小
196 0
|
3月前
|
网络性能优化
DP读书:鲲鹏处理器 架构与编程(六)PCI Express 总线
DP读书:鲲鹏处理器 架构与编程(六)PCI Express 总线
61 0
|
3月前
|
芯片
动画图解常见串行通讯协议:SPI、I²C、UART、红外分析
动画图解常见串行通讯协议:SPI、I²C、UART、红外分析
99 0
|
SoC
深入理解AMBA总线(十六)AXI设计的关键问题(二)
深入理解AMBA总线(十六)AXI设计的关键问题(二)
568 0
深入理解AMBA总线(十六)AXI设计的关键问题(二)
|
缓存 内存技术
深入理解AMBA总线(十六)AXI设计的关键问题(一)
深入理解AMBA总线(十六)AXI设计的关键问题
335 0
|
调度
METSO IOP111 比特流用于在部署时对设备进行编程
METSO IOP111 比特流用于在部署时对设备进行编程
93 0
METSO  IOP111 比特流用于在部署时对设备进行编程
基于Verilog HDL与虚拟实验平台的计算机组成与CPU实验第九章:多功能运算电路
基于Verilog HDL与虚拟实验平台的计算机组成与CPU实验第九章:多功能运算电路
186 0
基于Verilog HDL与虚拟实验平台的计算机组成与CPU实验第九章:多功能运算电路
【数字IC手撕代码】Verilog奇数分频|题目|原理|设计|仿真(三分频,五分频,奇数分频及特殊占空比)
【数字IC手撕代码】Verilog奇数分频|题目|原理|设计|仿真(三分频,五分频,奇数分频及特殊占空比)
【数字IC手撕代码】Verilog奇数分频|题目|原理|设计|仿真(三分频,五分频,奇数分频及特殊占空比)
基于Verilog HDL与虚拟实验平台的计算机组成与CPU实验第七章:奇数骑
基于Verilog HDL与虚拟实验平台的计算机组成与CPU实验第七章:奇数骑
102 0
|
Perl
基于Verilog HDL与虚拟实验平台的计算机组成与CPU实验第四章:七段译码器
基于Verilog HDL与虚拟实验平台的计算机组成与CPU实验第四章:七段译码器
138 0