PCIe SerDes 全流程实战
数字部分——TL-流控
本项目聚焦于高速串行通信本身。PCIe 作为广泛应用的高速串行通信协议,其历史悠久,协议栈层次多、设计复杂;Synopsys IP 更是在工业级别上对 PCIe 协议做了完整实现。
因此,本文 不 针对数字逻辑的每一个细节展开说明;若需深入,可结合 SystemVerilog 代码与波形自行学习。
个人经验
- Transaction Layer 的核心目标是构建一个能够长期稳定、并保持顺序正确的数字信号传输通道。Transaction Layer最主要的功能就是流量控制。
- 流量控制旨在充分利用带宽,同时避免阻塞,是解决传输效率问题的关键机制。
- 以太网协议栈同样存在带有流控的 TCP 和不进行流控的 UDP;以太网的流控逻辑主要由软件实现,而 PCIe 的流控则完全由硬件层面完成。
- 与以太网应用层的字节流语义不同,PCIe 应用层的语义体现为内存读写操作。
以下内容为O3-Pro对system verilog代码和标准文档的深度总结
1 背景:为什么 PCIe 要用信用(Credit)而不是简单的 XOFF/XON?
- PCIe 采用 链路级重发 + 端到端原子事务 的体系。
- 如果用传统 Pause / Resume,会由于 重发带来的带宽毛刺 和 TLP 顺序要求 导致 死锁或不公平。
- 因此规范在节 2.6 中提出:
“Flow Control is point‑to‑point (across a Link) and not end‑to‑end” – PCIe Base Spec 5.0 § 2.6.0.
信用被细分为 六类(PH/PD/NPH/NPD/CplH/CplD),以 4 DW 或 1 Header 单位 计量,覆盖三大 Transaction Class:P / NP / Cpl。
2 信用模型与硬件寄存器映射
缩写 | 对应 TLP | 发送端计数器 | 接收端计数器 |
---|---|---|---|
PH | Posted Header | CREDITS_CONSUMED_PH |
CREDITS_ALLOCATED_PH |
PD | Posted Data | CREDITS_CONSUMED_PD |
CREDITS_ALLOCATED_PD |
… | … | … | … |
“For each type of information … two quantities are tracked: CREDITS_CONSUMED and CREDIT_LIMIT” – PCIe Base Spec 5.0 § 2.6.1.1
在 Synopsys IP 中,这对寄存器由 产生端 rtlh_fc_gen.sv
和 接收端 rtlh_fc_decode.sv
组合实现:
// 发送侧累加器(节选)
rtfcgen_ca_pd_org <= rtfcgen_ca_pd_org + radm_rtlh_pd_ca; // ALLOCATED
rtfcgen_cr_pd <= next_cr_pd; // CONSUMED
// 接收侧广告(节选)
rx_rfc_data <= rdlh_rtlh_dllp_content; // DLLP 携带 CREDIT_LIMIT
这些寄存器通过 InitFC1 / InitFC2 / UpdateFC DLLP 在链路上传递,从而完成 “水桶” 的初始化与补水。
3 工作流:VC0 初始化全过程
下图给出了 VC0 自上电到可发包的状态机(来自 rtlh_fc_arb.sv
)。浅蓝色箭头为 FC1 Triplet(PH/NP/Cpl),浅红色箭头为 FC2 Triplet:
stateDiagram-v2 [*] --> S_FC1_P : LinkUp\nmore_vc_uninited_1 S_FC1_P --> S_FC1_NP : FC1-P Ack S_FC1_NP --> S_FC1_CPL S_FC1_CPL --> S_IDLE : all_fc_init1_done\nFC1-Cpl Ack S_IDLE --> S_FC2_P : FC1 全部完成 ...
代码映射
fc_state == S_FC1_P -> 发送 fc1_p_data
fc_init_req_hi -> VC0 或计时 32 µs 超时转高优先级
此逻辑与规范 “InitFC1 DLLP 必须在 Link 进入 L0 后 32 µs 内完成” 完全一致。
4 发送端“水闸”——CREDITS_CONSUMED vs. CREDIT_LIMIT
发送端每当 TLP 通过 Flow Control Gate,就执行
CREDITS_CONSUMED := (CREDITS_CONSUMED + Increment) mod 2^[FieldSize]
在 ku5p_rtlh_fc_gen.sv
中对应:
// 计算差值
assign rtfcgen_pd_diff = rtfcgen_ca_advert_pd - rtfcgen_cr_pd;
// Gate 判断
p_fcupdt_req = (non_infinite_p) && (p_timeout_30us | recovery_from_exhaustion_p);
rtfcgen_ca_advert_pd
= CREDIT_LIMIT(上次广告值)rtfcgen_cr_pd
= CREDITS_CONSUMED
只有当差值 ≥ 待发送 TLP 所需 PD 单元时,数据面模块 xtlh
才会真正把 TLP 往下游 xdlh
推送,否则在 xtlh_ctrl_halt
上打 back‑pressure。
5 接收端“补水”——UpdateFC 触发点
规范 § 2.6.1.2 强调两种场景必须 立即 发 UpdateFC:
- 队列耗尽后第一次归还
- 剩余 PD/CplD 信用 < Max_Payload_Size 时任何归还
在 RTL 中对等的判断:
recovery_from_exhaustion_p <= rtfcgen_ph_diff == 0 && clked_radm_ca_p;
recovery_from_insufficiency_p <= rtfcgen_pd_diff < int_max_plyd_cr;
当 need_update_p
为 1 且 fc_latency_timer_expired
,模块 rtlh_fc_gen
把 fcu_p_data
写入 rtfcgen_fc_data
,并拉高 rtfcgen_fc_req_hi
——这就是一个高优先级 UpdateFC DLLP。
6 30 µs 周期性更新与 8 µs Latency Timer
PCIe 建议 30 µs 周期 主动更新,以应对链路安静时信用倒计时失步的问题。Synopsys IP 在 rtlh_fc_arb.sv
内核化了一个 中心 8 µs counter + per‑VC 4 bit prescaler:
if (timer8us_timeout) fc_timer <= fc_timer + 1;
fc_update_timer_expired = (fc_timer >= (cfg_ext_synch ? 4'b1111 : 4'b0100));
cfg_ext_synch
=1 → 把 30 µs 放大到 120 µs(符合扩展同步模式)。- 每当 UpdateFC Triplet 发送完,
fc_timer
自动复位,确保周期稳定。
7 Watch‑Dog:200 µs 无 DLLP → Link Recovery
为避免远端失联,规范允许 200 µs 未收到任何 DLLP 即强制 LTSSM 进入 Recovery。对应逻辑:
ext_wdog_timer <= timer8us_timeout_wd + ext_wdog_timer;
rtlh_req_link_retrain <= (ext_wdog_timer == WDOG_EXP_VALUE) & timer8us_timeout_wd;
只要 xadm_all_type_infinite
=1(远端无限信用)或 cfg_fc_wdog_disable
=1,会自动屏蔽看门狗,以免在“无限信用”模式误触发。
8 Traffic Class → Virtual Channel 映射
在多 VC 设计里,TC 到 VC 的静态映射由软件写入 VC Resource Table,硬件侧通过
rtfcgen_vc = cfg_tc_struc_vc_map[tc*3 +: 3];
在接收路径 rtlh_tlp_check.sv
中,同一个时钟把 TC 解码后打到 rtfcgen_vc
,供 FC 账本使用,实现 “同 VC 无阻塞,不同 VC 互不影响” 的典型分级 QoS。
9 高速串行视角下的 Flow‑Control 深层机理
- 摆动窗口(Sliding Window)
CREDIT_LIMIT 与 CREDITS_CONSUMED 本质上是两个 模 2^N 的指针,天然支持 Pipeline 式“转账”,避免 ACK 型停顿。 - 高带宽延迟积(BDP)
16.0 GT/s × x16 × 4096 B payload → BDP 约为 128 KiB,远超最小信用。实际实现常常 over‑size buffer,再借cfg_fc_credit_*
软件调阻尼。 - 功耗友好
当进入 L0s/L1,UpdateFC 周期放宽到 120 µs,可显著降低电平翻转;只有smlh_in_l0_l0s
时才允许冻结计时器。 - 死锁避免
规范 2.4 的 Ordering Rules 决定了 NP/Cpl 可以越过被 PD 缺信用阻塞的流;rtlh_fc_gen
里通过分离的p_timeout_30us / np_timeout_30us
实现此策略。
10 调试 Tips & 常见陷阱
现象 | 快速定位信号 | 可能原因 | 处理经验 |
---|---|---|---|
VC0 永远发不出 TLP | rtlh_fc_init_status[0]=0 |
没收到远端 FC2 | 检查 LTSSM 是否在 L0,逻辑分析仪抓 DLLP 类型 0x28/0x29 |
周期 30 µs 出现带宽抖动 | rtfcgen_fc_req_hi 周期性抖 |
UpdateFC Triplet 过多 | 增加接收 FIFO 深度或调大 cfg_fc_latency_value |
Data Parity Error | xtlh_data_parerr |
ECRC 插入后 Parity 未重算 | 开启 XTLH_PIPELINE_CRC 并复核时序 |
11 小结
- 基于信用的流控 通过 Header / Data × P/NP/Cpl × VC 六维配额,实现了 点到点无停止、高带宽利用率、严格顺序保证 的链路协议。
- Synopsys IP 中各模块严格复现了规范算法,并提供 计时器、看门狗、优先级仲裁 等工程级增强。
- 熟练掌握 InitFC/UpdateFC 时序 与 CREDIT 差值指针,配合 波形观测 DLLP,是调通高速串行链路的关键。
“Flow Control credit return is used for receive buffer management only, and agents must not make any judgment about the Completion status …” – PCIe Base Spec 5.0 § 2.6.1.1