前面在介绍 PCIe 物理层逻辑子层的文章中,有提到过弹性缓存(Elastic Buffer,又称为 CTC Buffer 或者 Synchronization Buffer)。其本质上是一种 FIFO,主要用于解决跨时钟域问题。当然,PCIe 的弹性缓存还用于补偿时钟 误差(Compensate for the clock differences)。实际上,除了 PCIe,弹性缓存 还广泛应用于其它的高速串行接口——USB、InfiniBand、Fibre Gigabit Ethernet 等基于 SerDes 的应用。
由于 PCIe 采用的基于 8b/10b 的嵌入式源同步时钟,接收端存在两个时钟 域:一个是通过 CDR 从数据流中解析出来的时钟,用该时钟对数据进行采 样;另一个是本地时钟域,用于其他的逻辑的。借助弹性缓存(FIFO),可 以实现数据在这两个时钟域的转换。
以 PCIe Gen1 为例,链路上的数据速率为 2.5Gbps。但实际上,任何晶振 (或者其他频率发生器)都是有误差的,PCIe ±300ppm(Parts
Per
Spec 允许的误差范围为
Channel、
Million)。即,链路上实际的频率范围为
Ordered
2.49925GHz~2.50075GHz。借助弹性缓存,通过删除或者插入 SKP Set 可以消除链路频率误差的影响。如下图所示:
需要注意的是 PCIe Spec 并没有规定弹性缓存的具体位置,设计者可以将
弹性缓存放在 8b/10b 解码器之前,也可以把弹性缓存放在 8b/10b 解码器之 后。不过,Mindshare 的建议是将弹性缓存放置于 8b/10b 解码器之前的。
当本地时钟域的时钟(Local Clock)的速度比数据流通过 CDR 解析出的 时钟(Recovered Clock)的时钟要快时,且弹性缓存即将被读空之前,可以 向 SKP Ordered Set 中插入 1~2 个 SKP。如下图所示:
当本地时钟域的时钟(Local Clock)的速度比数据流通过 CDR 解析出的 时钟(Recovered Clock)的时钟要慢时,且弹性缓存即将溢出之前,可以从 SKP Ordered Set 中移除 1~2 个 SKP。如下图所示:
需要特别注意的是,Intel 提出的 PIPE 规范(并非 PCI-SIG 强制的规范, 具体参考前面关于 PIPE 的文章)中,只允许每次从一个 SKP Ordered Set 中 插入或者移除一个 SKP。如果需要插入或者移除两个 SKP,则需要对两个 SKP Ordered Set 进行操作。如下图所示:
因篇幅问题不能全部显示,请点此查看更多更全内容