数字部分 2.7 Tl 流控

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 DW1 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:

  1. 队列耗尽后第一次归还
  2. 剩余 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_genfcu_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