PCIe SerDes 全流程实战
数字部分——TL-原子操作
本项目聚焦于高速串行通信本身。PCIe 作为广泛应用的高速串行通信协议,其历史悠久,协议栈层次多、设计复杂;Synopsys IP 更是在工业级别上对 PCIe 协议做了完整实现。
因此,本文 不 针对数字逻辑的每一个细节展开说明;若需深入,可结合 SystemVerilog 代码与波形自行学习。
个人经验
在 SoC 与操作系统中,原子操作与中断同属核心机制,这也是专门撰写一篇介绍 PCIe Atomic TLP 的原因。
在 Linux 体系结构内,互斥锁(mutex,lock/unlock)与 CAS 锁语义不同。传统的 lock/unlock 需要对整个系统总线加以锁定;而 CAS 语义更为高效,由 PCIe 提供的 Atomic TLP 承载,可在硬件层面完成复杂的并发控制,降低系统负荷。此处仅讨论语义层面,实际实现中,操作系统及硬件平台往往会进行针对性的优化。
以下内容为O3-Pro对system verilog代码和标准文档的深度总结
1 前言
在 PCI Express (PCIe) 3.0/4.0/5.0 体系里,Atomic Transaction Layer Packet (Atomic TLP) 为软硬件提供了“总线级自旋锁”的能力:它让 Endpoint / Root Complex 能够直接对对端的内存地址执行 Fetch‑Add、Swap、Compare‑and‑Swap(CAS) 等原子语义,而不必再依赖传统的 锁寄存器 + 轮询 方案。
2 Atomic TLP 在标准中的定义
“AtomicOp Requests and Completions must be formatted such that the first byte of data following the TLP header is the least‑significant byte of the first data value…” — Base Spec § 2.2.2
请求类型 | 32 bit Operand | 64 bit Operand | 128 bit Operand |
---|---|---|---|
FetchAdd/Swap | Length = 1 DW | Length = 2 DW | N/A |
CAS | Length = 2 DW | Length = 4 DW | Length = 8 DW |
“If the Length field does not match an architected value, the Completer must handle the TLP as a Malformed TLP.” — Table 2‑12 注
此外,标准强制 地址天然对齐:32/64/128 bit CAS 必须落在 4/8/16 byte 对齐地址,否则同样判为 Malformed TLP。
3 Synopsys IP 中的 Atomic 路径
3.1 TLP 解析检查
ku5p_rtlh_tlp_check_slv.sv
第 ≈ 420 行 通过常量表枚举原子 opcode,并在收到 Header1 时立刻分类:
assign atomic_op = (tlp_fmt_type[6:0] == `FETCHADD32)
| (tlp_fmt_type[6:0] == `FETCHADD64)
| (tlp_fmt_type[6:0] == `SWAP32)
| (tlp_fmt_type[6:0] == `SWAP64)
| (tlp_fmt_type[6:0] == `CAS32)
| (tlp_fmt_type[6:0] == `CAS64);
紧接着做 三类约束校验:
assign atomic_operand_err =
atomic_op && !(operand32 | operand64 | operand128);
assign atomic_addr_align_err = (operand32 && addr[1:0] != 2'h0) ||
(operand64 && addr[2:0] != 3'h0) ||
(operand128 && addr[3:0] != 4'h0);
若任一条件为真,模块把 extrct_malfm_tlp_err
拉高,后端 FC 逻辑即视作 Malformed TLP 并丢弃。
3.2 Flow Control (NPH/NPD) 预算
Atomic TLP 属于 Non‑Posted Request with Data (NPD)。ku5p_rtlh_fc_gen.sv
里声明:
// AtomicOp Request consumes 1 NPH + n NPD units -- Base Spec Table 2‑42
IP 在 recovery_from_exhaustion_np
分支中对 NPD credit 低于 2 进行抢占更新(§ 2.6.1.2.d 规则),确保 128 bit CAS 仍能一次进链路。
3.3 ECRC 插入
当 Header.TD=1 且 merged_tlp_add_ecrc
置位时,ku5p_xtlh_ctrl.sv
状态机进入 S_ECRC
,把 32‑bit CRC 附在最后一个 DW。若上层驱动想禁用 ECRC,可清除 DevCtl2.ECRC_EN,并观察此状态分支不再进入。
4 高速串行链路上的“原子语义”
- 不可分割帧
Atomic TLP 在数据链路层视为普通 Non‑Posted,但由于 Completer 必须在写入前先读旧值,链路上永远是 Request → Completion with Return Data 对。 - 顺序性
- 在同一 Traffic Class 内,表 2‑39 把 AtomicOp 归为 NPR with Data。因此 Posted Write 可以越过它避免死锁,但另一 Atomic 不能越过它。
- 若软件需要更强顺序,可在发 Atomic 前后插入 Memory Write 并利用 PCIe No_Snoop 与 CPU fencing 保证可见性。
- Poison 传播
Synopsys RTL 在xtlh_ctrl
的wreq_poisoned
/cpl_poisoned
检测 EP 位,满足 Base Spec § 2.7.2.2。若 Root Port 启用 Downstream Port Containment,Poisoned Atomic 会触发 DPC 并强制返回 UR/CA Completion。
5 与 SoC Cache 和操作系统的协同
5.1 Cache 一致性路径
- LL/SC vs Atomic TLP
CPU 的 Load‑Linked/Store‑Conditional 仅保证 片内 L1/L2 原子;跨 PCIe 必须退化成 locked 指令或驱动发出 Atomic TLP。 - 目录缓存(DCT)
当 RC 把下行 Atomic 目标映射到 MMIO‑coherent region,Last‑Level Cache 需在 Receive Completion 时作 snoop‑invalidate;否则旧值可能仍驻留 L3,违背 Compare‑and‑Swap 语义。
5.2 OS 屏障与驱动接口
- Linux ≥ 4.5 增加
PCI_EXP_DEVCAP2_ATOMIC_ROUTE
能力位探测; - 驱动可调用
pci_set_atomic_op(pdev, PCI_EXP_DEVCTL2_ATOMIC_REQ);
并在关键路径前后使用 dma_wmb()/dma_rmb()
;相当于 x86 的 mfence
,ARM 的 dmb ish
.
- 若平台禁止 Atomic,驱动应 fallback 到
spin_lock_irqsave() + MMIO write
.
6 实战:64‑bit Fetch‑Add 流程
时序 | TLP | 关键字段 |
---|---|---|
t0 | Request | Fmt/Type = FetchAdd64, Length=2DW, Addr[2:0]=000 |
t1 | 链路层消耗 1 NPH+2 NPD credit | rtfcgen_ca_npd ‑‑ |
t2 | Completer 读 8 B 旧值,执行 +Δ |
— |
t3 | Completion | Byte Count=8, Status=SC, Data=旧值 |
Synopsys rtlh_fc_gen
在 t1 时刻把 rtfcgen_npd_diff
计数减 2;Completion 回来时 rtfcgen_incr_amt
加 1 CPID + 1 CPIH,credit 自动归还。
7 测试与调试建议
- 生成器:使用 pcie-tlp-gen 工具构造所有 32/64/128 bit Atomic 序列,覆盖 mis‑aligned 地址与非法 Length 以触发
rtlh_radm_malform_tlp_err
。 - 逻辑分析:在 FC 信号
rtlh_xdlh_fc_req
上打探针,确认 NPD credit 更新提前于后续 FetchAdd。 - 性能计数:统计
xtlh_xmt_tlp_done
与xtlh_xmt_tlp_done_early
差值,评估 Pipeline Register 带来的额外延迟。 - 系统软件:在 Linux 添加
pci=noatomic
内核参数,比较锁竞争下两种代码路径的 RFO latency。
8 总结
Atomic TLP 把 原子加/互换/比较交换 直接下沉至 PCIe 链路,极大降低了 NUMA‑SoC 内外同步开销。硬件需同时实现:
- 协议层面:Length‑Operand‑Align 三重校验、流控余量抢占、Poison 处理;
- 体系结构层面:LLC 刷新与 Memory Barrier;
- 软件层面:驱动能力协商与错误回退。
Synopsys DWC RTL 已为这些规则提供了清晰的钩子:tlp_check_slv
负责语法合法性,rtl*_fc_*
负责 NPD credit,xtlh_ctrl
负责 ECRC/错误上报。理解这些路径,既能指导后端时序收敛,也能帮助系统软件调优 Atomic 指令的实效性。
——完