转自:http://www.eefocus.com/liu1teng/blog/12-02/237897_4533d.html
前一段时间画了一块千兆扩展板,板子上有千兆网口和千兆光纤接口,两种介质可以通过跳线来转换,板子做好之后进行回环测试时,发现网口会有随机的丢帧现象,而光口是正常的,一直没有找到问题根源,后来在做另一个项目里,需要写MAC的时序约束,发现Xilinx提供的MAC硬对‘RX_CLK’的时序约束要求很高,建立时间只有2.5ns,保持时间0.5ns,无论怎么反复修改这个约束值都无法达到约束要求,最后仔细研究了一下,发现评估板上的PHY芯片,‘RX_CLK‘这个信号连接在GC_CLK,而我的硬件设计只连接在普通IO口上,在时序约束时,用CLOCK_DEDICETED_ROUTE=FLASE绕过PAR的检查,这样就只是将本该接入专用时钟管脚(或者叫做全局时钟管脚)的信号,接到了普通IO口上,但并没有做好如何用普通IO口来引入全局时钟,Xilinx官方论坛上更是有老外直接指出这只是把一个error变成了warning,并没有解决真正的问题。作为初学者的我并没有意识到,什么是‘真正的问题’,直到出现这种丢帧现象之后,才慢慢意识到FPGA并不是我之前想象的那么‘简单顺手’。
现在说说专用时钟引脚,它的出现具体原因可以说是FPGA自身的实现结构引起的,FPGA实现时,具体的时钟大概有外部供给FPGA的工作时钟,由DCM或者PLL产生的时钟,和FPGA输入输出数据的随路时钟;再说说FPGA的实现,由于是基于触发器的设计实现,这就造成了,在布局布线时,同一时钟域但是布局相隔较远的同步器件再被相同时钟触发时,会有延时,这反映在时钟的skew(相位倾斜),为了解决这个问题,时钟树就出现了,将时钟的布线成树形结构,使得到达每一个逻辑单元的时钟信号同相,这样就可以实现同步,这就是全局时钟网络,GC_CLK。也就是说GC_CLK在FPGA内部是固定的位置,与其对应的引脚也就固定了,这样的引脚称为全局时钟引脚GC_CLK PIN。实际上,综合器会将扇出的较大的信号当做全局信号,并自动在引脚上加入IBUFG,但是只有全局引脚之后才有IBUFG,所以如果UCF中的时钟管脚不是用的GC_CLKPIN,PAR就会报错,反之,当一个信号分配的是GC_CLK PIN,无论是否扇出足够大,都会加入IBUFG,这也其实是FPGA内部结构造成的,只有全局管脚上有IBUFG,所以只要该信号用了全局管脚,无论是,或不是全局信号,IBUFG都在那里。
再说说GC_CLK和CC_CLK的区别,由于GC_CLK PIN是最好用的时钟管脚,正常来说,凡是时钟信号,硬件连接上都应该用GC_CLK PIN,但是这样的PIN太少了,高端的FPGA也就十几个而已,V5系列最大的的200T也只有24个,所以很多时候满足不了实际应用对时钟的需求,这时就出现了代替品CC_CLK,CC_CLK只能保证同一BANK或者相邻BANK的时钟信号同相,并且无法用BUFER驱动,(这一点我不是很理解,以后用到了会补充上来。)简单地说,就是有GC_CLK就要用GC_CLK,没了,就用CC_CLK,如果用普通的IO口,就会有一些问题要注意。
回到之前所说的FPGA内的时钟,工作时钟的管脚是固定的,没啥说的,一定最全局的时钟管脚,内部由DCM或PLL产生的时钟,DCM的输出会自动接入全局时钟网络,最后一个其实是我曾忽略过的,输入输出的随路时钟,如果硬件上接到了普通IO上,这就有点悲剧了,尽管可以用BUFG接进全局时钟网,但是,从PAD到BUFG的输出有10ns的固有延时。这10ns无法消除,所以如果时钟频率超过20M左右时,skew会比较大。一些处理办法:用两个DCM级联来调相BUFG+DCM+DCM。千兆网口要跑125Mbps,时钟周期是8ns,如果固有延时是10ns,那么就有1/4周期的延时,我打算用前一级调相90°,后一级调相180°,这样就可以达到同相了吧。但随之而来的问题就是10ns的固有延时是否是稳定的(这个延时量也是官方论坛里的一大牛说的,没查到可靠的出处),两级DCM调相是否能保证无偏差。这都是要看实际的程序在板子跑的结果来下结论了。
板子回来后,在实际中的使用,出现了以下现象:按固定的最小帧间隔发以太网帧,以千兆标准96ns,出现错帧现象,如果以十兆标准9600ns,就没有任何丢帧现象,我想接口板还是没有完美的达到高速通信的要求,原因最可能是上述专用管脚的使用或者接口板经过插针无法支持高速传输,这只能再一一排除了。