数字部分 2.2 MAC Ltssm

PCIe SerDes 全流程实战

数字部分——MAC-LTSSM链路训练

本项目聚焦于高速串行通信本身。PCIe 作为广泛应用的高速串行通信协议,其历史悠久,协议栈层次多、设计复杂;Synopsys IP 更是在工业级别上对 PCIe 协议做了完整实现。
因此,本文 不 针对数字逻辑的每一个细节展开说明;若需深入,可结合 SystemVerilog 代码与波形自行学习。

个人经验

  1. LTSSM 是 PCIe 协议在物理层的初始化阶段,负责速率协商、均衡协商以及低功耗等功能。
  2. LTSSM 协商流程较为复杂,Synopsys 实现中 LTSSM 的单个 SystemVerilog 文件超过 3 800 行。
  3. 复杂性主要来源于以下因素:
    • 对 PCI 和 PCIe 的前向兼容与后向兼容需求;
    • 通道数量可调(1–16 Lane);
    • 需适应高插损与低插损等多种均衡场景;
    • 满足桌面端、嵌入式与数据中心等不同应用需求。
  4. 调试时,应在 PHY 稳定后拉高 LTSSM_enable 信号,以触发链路训练过程。

以下内容为O3-Pro对system verilog代码和标准文档的深度总结

PCI Express Base Specification 4.0 §4.2.4
“The Link Training and Status State‑Machine (LTSSM) is responsible for configuring and initializing the Link, negotiating Link width and data‑rate, managing error recovery, and restarting a Port from low‑power states.”

1 LTSSM在系统中的位置与作用

LTSSM 运行在 Physical Layer / MAC 边界,结合 PIPE‑PHY、Link Layer 以及电源管理模块完成以下关键职能:

目标 实现手段 本设计中核心信号/代码
检测对端并建立初始链路 Detect.Active / Polling.Active phy_mac_rxdetected, cfg_lane_en, S_DETECT_ACT
协商Lane 数 & Link Width Configuration.Linkwidth.* ltssm_lanes_active, S_CFG_LINKWD_START
协商数据速率(x1 Gen1→Gen6) Recovery.Speed / Equalization mac_phy_rate, current_data_rate, S_RCVRY_SPEED
建立 位/符号锁 & Lane 去斜 TS1/TS2 + EIEOS/SDS rmlh_deskew_complete, deskew_lanes_active
进入/退出低功耗 (L0s/L1/L2/L3) L0s、L1/L23 子状态 pm_smlh_entry_to_l1, rmlh_rcvd_eidle_set
错误恢复 Recovery.RcvrLock / RcvrCfg / Idle rmlh_deskew_alignment_err, smlh_eidle_inferred
热复位 / 协议复位 HotReset.Entry/HotReset latched_direct_rst, S_HOT_RESET_ENTRY
环回测试 Loopback.Entry / Active / Exit cfg_lpbk_en, 多段 lpbk_entry_state

理解这些宏观职责后,再看源码及波形就能迅速定位问题。

1.1 LTSSM 速查表

编码 状态 Base Spec 要点(节选) 代码符号 波形验证关键点
000000 Detect.Quiet 端口上电后保持电平;RX 端处于 Hi‑Z;等待 12 ms S_DETECT_QUIET phy_mac_rxdetected==0timeout_12ms
000001 Detect.Active 置位 RxDetect/RxStandby;等待 RX[0] 拉高 S_DETECT_ACT int_rxdetect_done 上升
000010 Polling.Active 发送 TS1;侦测全宽后转 Configuration S_POLL_ACTIVE xmtbyte_ts1_sent 1024 次统计
000100 Configuration.Xxx TS1/TS2 协商宽度/Lane# S_CFG_* link_latched_live_* 组合
000111 Recovery.RcvrLock “锁链恢复” —— TS1 训练 S_RCVRY_LOCK TS1 ≥1024 个连续、deskew_complete

2 Synopsys ku5p_smlh_ltssm 模块扫盲

2.1 顶层接口速览

端口 方向 说明 调试要点
ltssm[5:0] O 当前状态编码 建议在波形中着色以宏观查看迁移路径
ltssm_cmd[3:0] O 发送端动作:XMT_IN_EIDLE / SEND_TS1 / … xmtbyte_*_sent 配合验证
current_data_rate[2:0] I 0‑Gen1, 1‑Gen2, 2‑8 GT/s, 3‑16 GT/s, 4‑32 GT/s mac_phy_rate 一起反映协商结果
xmtbyte_ts1_sent / ts2_sent I 单个 Ordered Set 发送完毕脉冲 用来统计 1024 TS1、16 TS2 触发迁移
rmlh_rcvd_eidle_set I 捕获到 EIOS L0/L0s/L1/L2 认定关键
smlh_lanes_rcving[N‑1:0] I 各 Lane 接收训练序列指示 Debug 多 Lane 去斜
timeout_* I 多颗 1/2/3/10/24 ms 计时器 标准严格规定最长等待时间

源码的 S_* 状态枚举与规范一一对应,编译时通过编译指令展开;手动对照《表 4‑1 LTSSM states》即可。

2.2 状态总览图

Detect.Quiet ─► Detect.Act ─► Polling.Active ─► Polling.Configuration
           ▲                         │
           │                         ▼
           └── Detect.Wait ◄── Polling.Compliance
...
Cfg.Complete ─► Cfg.Idle ─► L0 ─┬─► L0s (Tx/Rx)
                                ├─► L1 / L2 / L3
                                ├─► Recovery.Lock │
                                │                 ▼
                                ├─► Loopback.Entry → Loopback.Active → Loopback.Exit
                                └─► HotReset.Entry → HotReset

建议在波形窗口中同时放 ltssm[5:0]ltssm_lastltssm_cmd 三条总线,一目了然。


3 Detect & Polling —— 从“看见”到“互认”

3.1 Detect.Active

代码片段:

S_DETECT_ACT: begin
  if (int_rxdetect_done & all_phy_mac_rxdetected & ~retry_detect)
       next_lts_state = S_POLL_ACTIVE;
  ...
end
  • 关键信号
    int_rxdetect_done 由 PIPE PHY_STATUS 驱动,确认 Rx‑Detect 完成
    all_phy_mac_rxdetected = 所有被配置为活动的 Lane 上 rxdetected==1

  • 波形验证
    在 FSDB 中把 phy_mac_rxdetectedint_rxdetect_done 拉到一组,可见 Detect.Act 末尾所有选通 Lane 拉高一个比特时间,随后 LTSSM 跳到 00_0100 (Polling.Active)——与 ltssm 总线值 0x04 对齐。

3.2 Polling.Active —— TS1 洪流

“Ports shall transmit at least 1024 consecutive TS1 Ordered Sets before switching to TS2.” — PCIe 4.0 §4.2.4.1

  • 波形观测
    xmtbyte_ts1_sent 周期:640 unit = 64 ns;前 80 unit 高电平,低 560,正对应 15.625 MHz TS1 速率。第一段高脉冲 1 026 个 —— 完整满足“≥1024”规范;紧接出现 1.1 µs 静默进入 TS2 阶段(见题给表)。

  • 代码联动

xmtbyte_1024_consecutive_ts1_sent =
       cfg_fast_link_mode ? (xmtbyte_ts_pcnt>=16)
                          : (xmtbyte_ts_pcnt>=1024);
...
if (link_latched_live_all_8_ts_plinkn_planen_rcvd && xmtbyte_1024_ts_sent)
       next_lts_state = S_POLL_CONFIG;

实测当计数器 xmtbyte_ts_pcnt1024 且所有 Lane 至少收到 8 个 TS(1/2),next_lts_state 将置为 S_POLL_CONFIG (0x05)。


4 Configuration —— 宽度 & Lane 编号协商

PCIe 4.0 §4.2.4.10 描述协商顺序:Link‑width Start → Accept → Lane‑num Wait → Accept → Complete。
代码与状态命名保持一致:

设计状态 规范章节 条件 & 信号
S_CFG_LINKWD_START Configuration.Linkwidth.Start 任何 2 个 TS1 linkn/lanen 有效 (link_any_2_ts1_*_rcvd)
S_CFG_LINKWD_ACEPT Configuration.Linkwidth.Accept 所有 Lane 均收到匹配 TS1
S_CFG_LANENUM_WAIT Configuration.Lanenum.Wait 等待对端用正确 Lane 编号回应 (link_*lanen_rcvd)
S_CFG_LANENUM_ACEPT Configuration.Lanenum.Accept 所有 Lane 互认
S_CFG_COMPLETE Configuration.Complete 发送 TS2 16 个,Deskew OK

波形要点

  1. ltssm[5:0] 轨迹依次 0x06 → 0x07 → 0x08 → 0x09 → 0x0A,且 deskew_complete 拉高。
  2. ltssm_cmd 在 Start/Accept/Wait/Accept 均输出 SEND_TS1,到 Complete 切换 SEND_TS2

Lane PAD / K23.7 现象

x1 训练时,剩余 7 Lane 需发送 K23.7 PAD。代码 / 波形中可见:

ltssm_xk237_4lannum <= ~latchd_smlh_lanes_rcving;

PAD Lane 的 lnknum/lanenum 位被强制置 1(K‑code)。


5 Recovery —— 数据速率协商 & Equalization

5.1 Recovery.Lock –> Recovery.RcvrCfg

进入 S_RCVRY_LOCK 的条件:

  • 本端 至少发送 1024 TS1(若 cfg_ext_synch 置 1)。
  • 对端 全 Lane 收到 TS1/TS2,且 spd_chg==0EC==00b

源码验证:

if ( link_latched_live_all_8_ts_linknmtx_lanenmtx_rcvd
     && (cfg_ext_synch ? xmtbyte_1024_consecutive_ts1_sent : 1'b1))
     next_lts_state = S_RCVRY_RCVRCFG;

5.2 Recovery.RcvrCfg –> Recovery.Idle

标准要求 DSP 必须先收齐 16 TS2 再进入 Idle;USP 能早点进入。
设计用 link_xmlh_16_ts2_sent_after_1_ts2_rcvd 计数,配合 deskew_complete_i

if (link_latched_live_all_8_ts2_linknmtx_lanenmtx_rcvd
    && link_xmlh_16_ts2_sent_after_1_ts2_rcvd && deskew_complete_i)
        next_lts_state = S_RCVRY_IDLE;

Equalization (Gen3+)
当对端发送 “Modified TS2 Skip‑EQ / No‑EQ‑Needed” 且 Core 尚未 Link‑up,可利用协议特权跳过 EQ:

  • link_latched_live_all_8_mod_ts2_skip_eq_*int_rcvd_8_ts2_skip_eq
  • link_latched_live_all_8_mod_ts2_noeq_nd_*int_rcvd_8_ts2_noeq_nd

这些布尔在 Idle→L0 前向下层 EQ 模块发指令(int_bypass_gen3_eq / gen4_eq)。


6 进入 L0 —— Deskew、Idle 计数与最终 Link‑Up

“When operating at 2.5 GT/s and 5.0 GT/s the receiver shall observe at least 8 consecutive idle symbols before asserting LinkUp.”

代码路径:

if ((GEN1/2 rate) && rcvd_8idles && idle_16_sent)
        next_lts_state = S_L0;
...
always @(posedge) if (lts_state==S_L0) smlh_link_up <= 1;

波形中 smlh_link_uptime 828 261 抬高,与日志一致;同时 ltssm_in_training 由 1→0。


7 低功耗路径(L0s / L1 / L2)

  • L0s:两路子状态机

    • Tx:S_L0S_XMT_* — 先发 Idle/EIEOS,再发 N_FTS,最后 Wait/Idle。
    • Rx:S_L0S_RCV_* — 检测 EIOS 连续性,clked_rxstandby 控制 PHY standby。
  • L1 / L23

    • S_L123_SEND_EIDLE:发送一帧 EIEOS ,并等待对端 EIOS (latched_rcvd_eidle_set);若 2 ms 超时进入 Error_Enter_L1 路径。
    • S_L1_IDLE/S_L2_IDLE 仍保持 ltssm_cmd = XMT_IN_EIDLE

8 Hot Reset & Loopback

8.1 热复位

latched_direct_rst 置 1(由 cfg_reset_assert 或 App Reset 驱动),LTSSM:

L0/L1_IDLE ─► S_RCVRY_LOCK ─► S_HOT_RESET_ENTRY ─► S_HOT_RESET

S_HOT_RESET_ENTRY 使用 SEND_TS1 携带 HotReset 控制位;S_HOT_RESET 中继续 TS1 直到对端回应两个 TS1 带 HotReset=0,随后回到 Detect。

8.2 内/外环回

  • cfg_lpbk_en 上升沿 + DSP 接收到对端 TS1(Lpbk1) → S_LPBK_ENTRY
  • S_LPBK_ENTRY_EIDLE 要求速度切回 Gen1 并发送 EIEOS;之后 Tx 侧 16 TS1 with PAD 进入 Loopback.Active。
  • 退出环回采用 2 ms 超时或软件 Clear,经过 S_LPBK_EXITS_LPBK_EXIT_TIMEOUT 再回 Detect。

9 上行/下行差异及 Upconfigure

上行(USP)与下行(DSP)在 Configuration 阶段职责不同:

  • USP 把 Link Number / Lane Number PAD,等待 DSP 决定。
  • DSP 在 S_CFG_LINKWD_START 即用 xmt_ts_lnknum 发送自己的 Link#/Lane#。

Upconfigure‑capable (cfg_upconfigure_support=1) 时,链路可在 L0 后自行扩宽;ltssm_ts_auto_change 被拉高并在 Recovery.Lock 触发速率或宽度重协商。


10 电源管理接口 & PIPE 交互

  • mac_phy_rate[2:0] 通过 三级延迟 保证在 PIPE phy_status 全撤销后再改速。
  • 进入 RxStandby 依据 rxstandby_assertion_enable 策略位,结合
    • int_rcvd_eidle_rxstandby (已收 EIOS)
    • rate_change_flag (正在变速)
    • current_powerdown (P1/P2)
  • eiexit_hs_in_progress 用于阻止速率切换期间 RX standby 抖动。

11 深层初始化机制透视

初始化环节 波形/信号示例 标准引用
位锁定 (Bit‑Lock) xmtbyte_fts_sent 计数达 N_FTS “FTS provides bit‑lock… 130 × N_FTS UI”
符号/块锁 rmlh_all_sym_locked 拉高 §4.2.4.1 Training Sequences
极性检测 latched_lane_reversed §4.2.4.4 Lane Polarity
去斜 (Deskew) rmlh_deskew_complete §4.2.4.11 Lane‑to‑Lane De‑skew
DC Balance 跟踪 TS1/TS2 Symbol 14/15 自动替换 “Transmitters must evaluate running DC Balance…”
速率协商 latched_ts_data_rate 比较 + mac_phy_rate 更新 §4.2.4.9 Link Data Rate Negotiation

这些步骤在波形中可直接定位:从 Detect 到 L0 共需 ~830 µs(见时间轴 0→832 661 unit),与规范 < 1 ms 要求相符。


12 小结

  1. 状态机ltssm[5:0] 与规范逐一对照,配合 ltssm_cmd 可精确锁定阶段。
  2. 训练序列 — 使用 xmtbyte_ts*_sent 和波形周期计算,确认 TS1≥1024、TS2≥16。
  3. Deskew & Equalizationrmlh_deskew_complete 和 “Modified TS2 Skip‑EQ” 信号帮助加速 Gen3+ 训练。
  4. 恢复 / 低功耗 — 计时器、EIOS 检测与 rxstandby handshake 共同保障快速且可靠的电源转换。
  5. 调试策略 — 建议“状态‑命令‑计数器‑关键脉冲”四组信号固定放在波形模板,出现异常抓住第一跳转点即可定位。

结合本文的 代码摘录 + 波形解析 + 标准条文,你可以为同事构建一套完整的 LTSSM 实战教程,既能解释高阶串行链路的初始化机理,又能在测试或现场故障时直接落地调试。祝写作顺利、培训成功!