3、PIPE接口协议:PIPE 5.0/6.0信号定义、TX/RX数据通路、状态机切换
咱们开始讲 PIPE 接口。这是 PHY 和 Controller 之间的“对话协议”。说白了,Controller 通过 PIPE 告诉 PHY “发什么数据”、“收什么数据”、“链路状态怎么变”。我最早看 PIPE 5.0 spec 时,光信号列表就头晕,后来做了几个项目才理清脉络。
3.1 信号定义:Controller 和 PHY 的“接线图”
PIPE 接口分三大类信号:数据信号、状态控制信号、链路管理信号。PIPE 5.0 和 6.0 在信号数量上差别不大,但 6.0 为了支持 32 GT/s 速率,加了些边带信号。
先看一个最常用的 TX 侧信号表:
| 信号名 | 方向 | 位宽 | 功能 |
|---|---|---|---|
| TxDataK | Controller → PHY | 1 | 标识数据/控制符(0:数据,1:控制) |
| TxData | Controller → PHY | 8/16/32/64 | 待发送的并行数据 |
| TxElecIdle | Controller → PHY | 1 | 电气空闲使能 |
| RxDataK | PHY → Controller | 1 | 接收数据/控制标识 |
| RxData | PHY → Controller | 8/16/32/64 | 接收到的并行数据 |
| RxValid | PHY → Controller | 1 | 接收数据有效指示 |
| PowerDown | Controller → PHY | 2 | 电源状态管理(P0/P1/P2/P3) |
| PhyStatus | PHY → Controller | 1/2 | PHY 状态反馈 |
为什么接口要留这么多信号?一个关键原因:协议分层。Link Layer 只需要关心数据和状态,不用知道 PHY 怎么锁相、怎么均衡。PIPE 就是那层“绝缘层”。
3.2 TX 数据通路:从 Controller 到 SerDes
数据怎么过去?不复杂。Controller 把 TxData + TxDataK 给 PHY,PHY 内部做 8b/10b 或 128b/130b 编码,再串行化发出去。
核心步骤:
- FIFO 写入——Controller 在一个 PIPE 时钟周期内把数据压入 PHY 的 TX FIFO。
- 编码——PCIe 用 128b/130b,UCIe 也是类似方案。注意控制符的插入,比如 SKP OS 对齐。
- 串行化——并行转串行,送到 SerDes 输出。
- 电气空闲控制——TxElecIdle 拉高时,TX 进入高阻态。
我这里用一段伪代码示意 TX 侧的状态判断:
always @(posedge clk) begin
if (TxElecIdle) begin
// 进入电气空闲
tx_serial_out <= 1'bz;
end else begin
// 正常发送数据
tx_fifo_wr_valid <= 1'b1;
tx_fifo_wr_data <= {TxDataK, TxData};
end
end
注意一点:PIPE 时钟频率和链路速率有直接关系。比如 UCIe 16 GT/s 用 32-bit PIPE,时钟就是 500 MHz。我做过一个板子,因时钟抖动太大导致 TX 误码率超标——后来换了低抖动振荡器才解决。
3.3 RX 数据通路:从 SerDes 到 Controller
接收侧更复杂一些。PHY 从 SerDes 拿到串行数据,先做 位锁定 和 字对齐,再解码成并行数据,最后通过 RxData/RxDataK 送出去。
RX 通路的关键环节:
- 时钟数据恢复 (CDR)——锁定 incoming 数据频率,这步出问题后面全崩。
- 块同步——找到 128b/130b 块的边界。
- 解码——去除扰码、恢复原始数据。
- 弹性缓冲——补偿收发时钟差异,避免溢出或读空。
- RxValid 生成——只有数据稳定有效时,PHY 才拉高 RxValid。
3.4 状态机切换:PIPE 的“生命线”
PIPE 状态机是整个接口的灵魂。它管理着 PHY 的电源状态和链路状态切换。PIPE 5.0/6.0 的状态定义基本一致:
- P0——正常工作,链路已初始化,数据收发正常。
- P1——低功耗待机,部分电路掉电,可快速恢复。
- P2——更深度的休眠,常结合 L1 电源管理。
- P3——完全掉电,链路复位后需重新初始化。
状态切换由 Controller 通过 PowerDown[1:0] 控制:
| PowerDown[1:0] | 目标状态 | 典型恢复时间 |
|---|---|---|
| 00 | P0 | — |
| 01 | P1 | 几十 ns 级 |
| 10 | P2 | 几 μs 级 |
| 11 | P3 | 需重新训练链路 |
为什么需要这么多状态?说白了就是功耗和性能的平衡。UCIe 常用于芯片间互联,功耗预算很紧。如果在空闲时还跑在 P0,功耗就浪费了。
状态机切换还有一个潜规则:PhyStatus 信号必须稳定后才算完成。有些 PHY 在状态切换过程中会短暂输出不确定值。我建议你的 Controller 加一个超时机制,如果 10 μs 内 PhyStatus 没给出期望值,就触发复位。
嗯,这里要强调一下:PIPE 状态机不是只有这四个状态。内部还有像 P0.1、P0.2 等子状态,用于管理 TX/RX 独立低功耗。但对外接口只暴露 P0-P3,内部子状态由 PHY 自行管理。
3.5 本章核心脉络
下面这张图总结了 PIPE 接口的核心关系——信号、通路、状态机,三者的配合构成了 Controller 和 PHY 之间的完整通信协议:
图中三条主线:信号是 Controller 和 PHY 之间的“文字协议”;数据通路(TX/RX)是数据流动的物理管道;状态机则管理电源和链路状态。三者缺一不可。
在实际调试中,我建议你先看 状态机是否稳定,再查 信号时序,最后定位 数据通路。这个顺序能帮你快速缩小问题范围。