PCIE串行总线上的传输信号属于差分信号,也是同步传输方式,但是没有专门的同步时钟!我们在设计电路时,通常会提供一组100MHz差分时钟给后端设备,这并不是上文所说的同步时钟。PCIe的时钟是嵌入到差分信号中的,PCIe总线在训练之初会完成一个bit lock,在这个过程中链路上会传输一段0和1间隔序列,即是连续的高低电平,就是用来给Receiver提取时钟的。Receiver提到到时钟后,才能够继续捕获一位一位的数据,也就是做bit的识别,再往后则是做多个bit的识别,即序列识别。在PCIe Transmitter里会进行编码操作,这个编码即是让0和1的数量更加均衡,以防止总线时钟丢失(正常数据传输过程中,也有可能发生失锁)。另外,总线处于空闲状态时,也会持续传输时钟对齐码流,以防止一不留神丢了时钟,突然有数据过来的时候找不着北。
同理symbol lock表示PCIe链路上获取开始训练的标记符COM字符的过程。每个lane 的 bit lock , 也即是:每个lane 完成了时钟恢复。bit lock:指CDR锁定,此时只是锁到bit,但不知道哪个是bit0
基本明白了PCIe总线上传输数据和传输时钟是怎么回事后,再来看看刚才被丢到一边的100MHz时钟,这位仁兄打什么酱油的。通常我们会为PCIe设备需要100MHz参考时钟,不论是Root还是switch还是endpoint,这个时钟我们称为参考时钟,而没有称之为同步时钟。PCIe controller内部电路运行是需要时钟的,这个100MHz参考时钟即是提供给controller使用的时钟,和任何一个电路系统需要时钟是相同的概念。100MHz时钟输入controller后,经内部PLL进行倍频再分给各部分电路使用。PCIe总线在不断升级,PLL倍频的最大值也在不断提升,当然controller内部的机制根据每个厂家具体情况而不同。既然100MHz时钟不是用来同步差分信号,而是用于controller内部的,那么PCIe总线两端的设备也是可以独立使用100MHz时钟源的,这种架构称之为独立时钟架构。用这种架构思考PCIe总线,就不那么容易将100MHz时钟认为是同步时钟了。
现在抛出本文要说明问题:当前我们在进行PCIe架构设计时常使用的是同源时钟架构,也即是PCIe的root和endpoint都使用同一个源头出来的100MHz参考时钟,在这种架构中会对时钟走线长度以及收发链路的时钟延时进行限制,为什么会有这样的限制?这个限制的依据是什么?要解决的问题是什么?本文就这个问题进行持续性分析,希望可以找到各方面的原因。
此问题首先涉及到一个与上文有关的疑问点:既然PCIe Receiver接受的数据是基于总线上恢复的时钟(使用CDR恢复的时钟),那么和100MHz参考时钟有什么关系,为什么要对100MHz时钟进行限制?(Tranmitter负责按照时钟节拍将数据打出去即可)这两个时钟兄弟有什么关系?这里涉及到Receiver内部的工作机制,其中有一个部件叫做Elastic Buffer——弹性缓冲,这个部件的作用即是将按照CDR恢复时钟采样得到的数据继续向后面电路传输时,进行一个过渡。为什么需要过渡?因为后面电路所采用的时钟就不是CDR恢复的时钟了,而是Receiver使用100MHz参考时钟进行倍频而得到的时钟。这里存在2个时钟,数据需要从一个时钟域传输到另一个时钟域,虽然前后的时钟被处理到了同一个频率,但谁也不能保证他俩频率完全一模一样,相位一模一样。理论上世间也会很难存在完全一样的事物,这也不是我们设计电路的目的。既然存在差异,这个差异会不会影响数据从一边传到另一边呢?
这里插入一个题外话,在其他信号的传输过程中也会遇到类似的问题,比如CPU的处理频率极高,每秒可以处理XXX级别数据,而数据要从机械硬盘取出来传输到CPU中进行处理,机械硬盘存取数据的速率比CPU处理数据的速率不知道慢多少倍,怎么办?先通过高带宽的总线把数据不停地从硬盘往内存搬,搬到一定数量后,CPU再过来一次拿走,这个过程CPU就短时间操作一次,其他时间处理其他事,而外围的内存、总线和硬盘则是不停在做搬运工作。这种方法可以称之为缓存:找个地方放东西,这个地方两边的人根据速率差异进行不同量的工作,以缓解两边的差异。那么PCIe Receiver的时钟差异问题,是不是也可以用这个方法,那不用,为什么?缓存两边设备的频率或者速率相差很大,同步几乎不可能。而上文中PCIe Receiver内部2个时钟的差异其实并不大,设计上是希望频率完全一致的,这种情况还用不着缓存。
弹性缓冲的工作原理如下图所示(图片摘自参考文件《Elastic Buffer Implementations in PCI Express Device》 Joe Winkles),buffer左侧数据进入使用CDR恢复的时钟采样的数据,属于恢复时钟域,buffer右侧数据取出则是controller使用100MHz参考时钟进行倍频后的本地时钟,属于本地时钟域。两个时钟由于各种不可控因素会存在很小的频率差异和相位差异,弹性缓冲是一个先进先出的缓冲空间,数据从左边进,然后按照进来的顺序再从右边出。入口和出口的差异使用SKP序列进行处理。
SKP序列是PCIe总线专门用于补偿时钟差异的特殊序列(下图摘自参考文件《PCIe 5.0 Base Specification》 PIG-SIG),这个序列不传输有效数据信息,简单来说是用来占位置的。SKP序列会在总线上定期插入(不出意外则定期插入)数据序列中占几个位置,具体占位置大小,不同代的PCIe不同。当SKP序列和有效数据序列一起被receiver采样进入到弹性缓冲后,也占用了弹性缓冲的若干位置。
SKP发挥作用的方式很简单,当数据进入的时钟频率(CDR恢复的时钟频率)大于数据出的时钟频率(本地时钟频率)时,数据进的比走的快,会导致进入buffer的数据累积越来越多,甚至可能溢出丢失,在这种情况下,则从buffer中抽出几个SKP,将位置空出来,那么数据就不会溢出了(下图摘自参考文件《Elastic Buffer Implementations in PCI Express Device》 Joe Winkles)。
当数据进入的时钟频率(CDR恢复的时钟频率)小于数据出的时钟频率(本地时钟频率)时,数据走的比进的快,会导致buffer的数据越来越少,甚至buffer被掏空,在这种情况下,则向buffer中插入几个SKP,填充buffer(下图摘自参考文件《Elastic Buffer Implementations in PCI Express Device》 Joe Winkles)。
通过抽走和插入SKP序列的方式,可以解决两边时钟频率差异的问题。弹性缓冲自身有状态检测功能,能够不断监测buffer内的数据量,从而做出响应,具体操作的SKP数量,根据不同厂家的controller设计而不同。
从弹性缓冲的工作原理可以看到,其对时钟差异的补偿量级,可能也只是可以操作的SKP数量所对应的时间,而一个SKP序列,在PCIE 5.0只有16bit数据,所对应的时间极短,由此弹性缓冲能够补偿的时间也是极短的。如果buffer两边的时钟相差很大,那么弹性缓冲也是无能为力的,因此对于时钟需要进行一个限制。
网友评论