4. 异步fifo(先进先出)
图是深度(depth)为8的异步fifo的示意图。其中,0~7代表8个寄存器,他们组成了一个环。
绿色的外圈代表写操作,按照顺时针方向(地址递增),依次写入不同的寄存器;写完所有的寄存器,再从寄存器#0开始,循环不断;写指针(wrtie pointer)代表当前写入寄存器的地址;写操作是写时钟的同步电路。
橙色的内圈代表读操作,按照顺时钟方向(地址递增),依次读取不同的寄存器,读完所有8个寄存器,再从寄存器#0开始,循环不断;读指针(read pointer)代表当前读取寄存器的地址;写操作是读时钟的同步电路。
图
对于特定寄存器,fifo必然是先写后读;fifo内部,读指针在不断追赶写指针。当写指针跑的太快,比如已经超越读指针一圈,这种状态就是写满(fifo full),这时候继续写入就会把覆盖(overwrite)未被读取的寄存器(上溢,overflow),造成数据的丢失;另一种情况,读指针等于写指针,这种状态就是读空(fifo empty),指向的寄存器还没有被写入,这时候继续读,读出来的是空的或者是上一个循环已经读取过的数据(下溢,underflow)。
写满(full):读指针 = 写指针 + fifo深度;
读空(empty):读指针 = 写指针;
写满和读空是两种边界状态,更多情况下,fifo处于写满和读空之间的中间状态。读指针和写指针之间的差值形成了水位图(watermark),代表着fifo的实际使用率。
异步fifo的实现有很多技术考量,最重要的是跨时钟域(cdc)问题:写指针和写满信号属于写时钟的时钟域;读指针和读空信号属于读时钟的时钟域。有很多文献讨论异步fifo的实现细节,有兴趣的可以参考文献。
异步fifo的设计已然成熟,经过封装后成为异步fifo模块(或者ip),比如图。我们可以直接调用而不必顾虑内部的细节。
图
图中,左侧是写操作,右侧是读操作,读写操作工作在各自的时钟域,互不影响。只要没有写满信号,写操作就可以一直持续;只要没有读空信号,读操作也可以一直持续。数据源源不断从左侧流向右侧。
5. rx弹性缓存(elastic buffer)
在以太网的接收端,pcs层使用弹性缓存来补偿时钟的ppm频率差异。
10b编码经过异步fifo,从rx时钟的时钟域转换到本地时钟域。
802.3标准没有提供异步fifo的实现细节,老戚从xilinx的用户手册找了一个1000base-x设计例子做为参考。
这是一个深度为32的异步fifo。计算读指针和写指针的差距,形成了图的水位图。
图
当水位上升时,意味着fifo读取的速度大于写入的速度;反之,则意味着fifo读取的速度小于写入的速度。
上篇说到,pcs和pma之间(tbi)的10b编码是连续的。读写时钟(本地时钟 vs rx时钟)的频率差异会导致水位或者上升到上溢,或者下降到下溢。
rx弹性缓存能够识别10b码型,然后根据水位来相应的插入或者删除特定的10b码型。
当水位上升到上半部灰色区间时,就删除idle码;
当水位下落到下半部灰色区间时,就插入idle码;
当水位处于中间区域时,既不删除也不插入。
图
mac层的以太网帧之间的间隙(ipg)最小是12字节(octets);而在pcs层,最小ipg转换成10b码型:/t/,/r/,5/i/*。(见上篇)
由于不能删除帧内数据,mac帧越长,频差积累的影响就会越大。
假设rx时钟频率为正偏100ppm,本地时钟频率为负偏100ppm,考虑最长的jumbo帧:
9216 byte * (1.0001 / 0.9999 - 1) = 1.84 byte
或者说,删除一个/i/(/i2/ = /k28.5/d16.2/)就足以补偿最大时钟ppm偏差。
如果rx的时钟慢于本地时钟,那么就需要插入idle码。
理想的水位是中间,比如16,这也意味着数据经过fifo的时候会有16x 10b (128ns)的延时。
6. 为什么还会丢包?
rx时钟慢于本地时钟的情况下,在rx的10b数据中插入idle码,ipg变大,不会造成问题;反过来,会删除部分的/i/,结果可能导致以太网帧的ipg被削减到标准之下,虽然并不损失正常数据,但是在mac层可能成为问题。
图
通常而言,交换芯片(点击进入:可编程交换芯片)的内部带宽会大于接口的带宽,所以入口(ingress)侧也不会丢包;在出口(egress)侧,mac却必须严格按照802.3标准恢复12字节的最小帧间隙,这会减缓发送的速度。可以想象,长时间的饱和流量会导致出口侧的缓存(packet buffer)越积越满。这种情况持续发生,最终会导致出口丢包。
图
对于交换机产品,端口之间互相打包(转发包)是最基本的验证测试项目(图)。我们期望线速(line rate,utilization 100%,最小ipg)不丢包,然而,经常会看到99.9999%就丢包了,丢的数量不多,短时间甚至看不出来;调到99.99%变好了;或者下调发包仪器(traffic generator)的参考时钟,比如-10ppm,丢包问题就消失了。当然,也有很多交换机按照100%速率转发包没有任何问题。究其原因,就是ppm时钟频率偏差引起的。
一个有意思的推论就是,虽然pcs能够补偿时钟的频率差异,同步以太网(synchronized ethernet)时钟驱动的时钟域,至少要包含mac层,而不仅仅是pcs phy。(sync-e下次聊)
部分以太网交换机的厂商会使用中心频率正偏25ppm的参考时钟,使得交换机的本地时钟处在相对高位,从而避免频差引起的丢包。但是,交换机之间的背对背连接呢?只要频率是本地产生的,总是会有高有低,这样做不能从根本上解决问题。
实际上,对于以太网的应用来说,ppm时钟偏差的影响并不大。不像sdh/sonet这种时分复用的系统,以太网包交换(packet switching)的优势在于带宽动态复用(或者统计复用,statistical multiplexing),企业级交换机(enterprise class ethernet switch)使用大缓存(packet buffer)来起到削峰填谷的作用。在mac层,802.3x流控(flow control)协议定义了pause frame,可以用来通知对端暂停发送一段时间。更上层,tcp支持出错重传,还有qos等等。
以上的讨论都是基于1000base-x。当以太网的端口速率上升到10g以上,8b10b编码就被64b66b替代了,降低了额外带宽开销,前提是pma层的cdr的技术提升(仅仅要求66b保证最少一次01转换);pcs层的idle码换了形式继续存在;8b10b检错变成了am控制码携带的bip(bit interleaving parity)。总的来说,形式变了,原理没有变。而且,不仅是以太网,pcie、sas、sata、usb等等也有类似的功能。
小结一下:物理层(physical layer)的物理编码子层(pcs - physical coding sublayer)对解决时钟ppm问题起了关键作用,pcs借助fifo处理跨时钟域,通过删除或插入idle码组,来补偿接收数据和本地时钟的有限频差,这就是弹性缓存(elastic buffer)。弹性缓存加上包缓存,对突发(burst)数据流量有完美的效果,却不能解决长时间线速(line rate)流量下的丢包问题。当然,通过802.3x流控或者更上层协议避免长时间线速。
为改善移动领域不佳状态 英特尔拟收购Nvidia
金立说凉就凉了 年产8000万台的“神话”
天然气计量的相关标准
关于PCB焊接问题、波峰焊缺陷及预防措施
大唐移动5G专家段滔:对5G芯片和终端提出新需求
以太网时钟的PPM频率偏差的解决方案(下)
LED显示屏发送卡设计
半导体新闻合集:中国集成电路行业平均月薪9120元 巨缺人才
基于ADSP-TS201DSP芯片实现卫星系统的数据采集卡设计
宝马2系Active Tourer上手体验评测
电感升压电路的原理
谷歌开发新操作系统Fuchsia
交流耦合 TIA 拒绝明亮的环境光源
基于GPRS的远程IAP系统方案的终端产品设计
5V,5W至15W电源如何实现预升压
5G竞赛全面打响 最大赢家会是广电?
为什么调用函数的时候,有些情况下要传地址?传地址有什么好处?
vivo聚光计划第四场落下帷幕,聚焦金融电商行业营销讨论
BGA和QFP之间的比较及发展趋势简介
微软新项目Insider20年前就实现了