"); //-->
掌握FPGA技能,从点滴做起。在调试FPGA板子的过程中,常遇到的BUG分为两类,一类是功能性的,仿真一下就能查到原因,并且这类问题往往是确定性的,也容易重现和解决;另一类就是时序问题,时序问题是由于电路设计的不合理导致(比如用软件的思想去写电路),这类BUG每次重现的现象往往都不一样,比如没有进行跨时钟域处理等问题,而接口上的时序问题往往最为常见。本文以Xilinx开发板上常见的FMC扩展接口为例说明一种时序问题的处理方法。
背景
在调试的FPGA板子的过程中,常遇到的BUG分为两类,功能性BUG和时序BUG。
第一种是功能性的,仿真一下就能查到原因,并且这类问题往往是确定性的,也容易重现和解决,比如本公众号之前介绍的搭建仿真环境的一些方法:Modelsim的安装与使用,用Modelsim独立仿真带Vivado IP核的仿真工程,如何用ModelSim 独立仿真ISE的仿真工程。这类问题中稍微有难度的就是仿真环境不容易重现的,或者需要跑很长时间仿真才能重现的,这一类问题本公众号之前介绍过一种解决方案,详见:Vivado进行FPGA调试“犯罪现场”,在仿真环境中重现方法;
另一种就是时序问题,时序问题是由于电路结构设计的不合理导致(比如用软件的思想去写电路,这就必须养成良好的硬件语言代码规范习惯,详见:干货!Verilog HDL初设计注意事项,Verilog HDL描述的组合逻辑环在FPGA实现时到底有什么问题?),这类BUG每次出现的现象往往都不一样,比如跨时钟域引起的不稳定等问题(解决办法参见:跨时钟域信号的处理方法)。
时序问题中往往以接口上的时序问题最为常见。而接口上的时序问题也经常分为两种,一种是驱动能力问题,另一种是时延问题。
驱动能力的问题也经常遇见,比如做AFDX或者TTE等双冗余可靠的网络是,常常需要一个对RGMII的网口进行冗余备份。这是如果直接采用连线的方式把一个网口的信号同时又连到另外一个网口上,这是常见的问题是一个网口可以稳定的收发数据,另一个网口则会出现不稳定的状态,比如无法正常收发数据或者丢帧等。这个问题就是典型的驱动不足的问题。Xilinx FPGA在解决驱动能力不足导致的问题时采用的是添加BUFIO的方法,对输入管脚进来信号都让其经过一级IDDR后再进来,对要输出的信号则让其经过一级ODDR后再输出。如下面两图所示。
另一种时序问题则是最常见的问题,一般是通过TCL脚本的约束文件来处理,但有时候脚本的控制能力有限,此时就需要通过添加Xilinx的IODELAY核来调整时序,本文以Xilinx开发板上常见的FMC扩展接口为例进行说明时序问题的处理。
VC709本身并不具有以太网接口,需要通过FMC扩展板转接获得以太网接口,VC709如图1所示(图1中红框为FMC接口),MeshSR四端口以太网扩展板如图2所示。
MeshSR四端口以太网扩展板板载一片四端口博通以太网PHY芯片,型号为BCM5464SR,通过扩展板FMC接口与VC709连接,并提供4个RGMII接口。
图1 VC709评估板
图2 MeshSR四端口以太网扩展板
问题及分析
搭建VC709+MeshSR扩展板硬件平台,并加载MAC核自回环程序,使用TestCenter打流(每个帧完全一样且速率恒定),TestCenter显示无正确数据帧接收,观察现象,发现如下结果:
(1) 观察TestCenter结果界面,发现收到的错误数据帧的数量与发送数据帧数量一致,说明没有丢包,但是数据包全都错了;
(2) 使用Wireshark加载TestCenter数据包缓存中的数据包(接收到的数据包),发现接收到的错包都是一样的(与发送的数据帧一样相对应),说明错误产生是很规律的;
(3) 使用嵌入式逻辑分析仪抓取FPGA内部接收和发送的数据帧信号,发现FPGA接收到的数据帧(其实也是FPGA发送的数据帧)与TestCenter接收到的数据帧完全一样,说明RGMII接口发送没有问题;
(4) 对比TestCenter发出的帧与收到的帧,发现存在信号错位现象。
综合上面四点,猜测是扩展板提供给VC709的RGMII接口,接收部分存在时序问题,导致被采样信号无法对齐,进而导致FPGA内部抓取的信号全都是错的。
以图3举例说明。Data是一条四位的数据总线,在时钟上升沿处(红色箭头处),其值应该为4‘b1111,但是由于PCB走线的原因,Data[1]延迟比其他三条内部连接线大,导致时钟上升沿处的采样结果为4’b1101,发生采样错误。
但是需要注意到,图3中蓝线位置四条连接线的值都是对的,如果给Data 总线人为地加入一些延迟,使时钟上升沿与蓝线位置对齐,那么采样得到的值就是对的。这就是下面的解决办法。
图3 采样错乱问题示例
解决思路
在上一节我们说道,可以人为地给Data总线添加一个固定且微小的延迟,使得时钟采样时(之所以说微小,是因为该延迟小于一个时钟,往往在几百皮秒到几纳秒之间),采到Data总线正确的位置,那么采样错乱的问题就可以解决。
加入延迟需要使用一个原语,即IODELAYE1,如图4所示,其各个端口的功能如图5所示。
图4 IODELAYE1原语
图5 IODELAYE1 接口信号
其中,信号C为该原语参考时钟,为延迟提供参考基准(一个标准延迟叫做一个tap),tap与参考时钟频率之间的关系是
,其中f为参考时钟频率从;CNTVALUEIN为5位信号,取值在0到31之间,该信号表示加入几个标准延迟。
举个例子,如果参考时钟频率为200MHz,则tap=78ps;300MHz,tap=52ps;400MHz,tap=39ps;125MHz,125ps;72.5MHz,216ps;如果CNTVALUEIN为0,则不加入延迟,如果该值为31,则加入31个tap大小的延迟。
上图中IODELAY的时延值采用VIO的方法可以在线调整,VIO的方法详见文章:使用VIVADO中VIO模拟CPU接口进行在线寄存器读写调试(附源代码),这样对于任何接口都可以用该方法很好的控制输入时延值了。等在线调整好时延值以后,就可以固定下来了。
RGMII接口时序处理
再总结一遍RGMII接口的时延调试方法:
1、时钟处理
上图中PHY芯片给过来的时钟信号rgmii_rx分成两路,一路需要经过一级BUFIO,产生信号rgmii_rx_clk_bufio,该rgmii_rx_clk_bufio信号只是在接口处使用,用于后续添加IODELAY时使用;另一路信号经过一级BUFR,产生rx_clk_int时钟信号,该时钟信号就可以作为全局时钟使用,可以驱动2-3个BANK范围内的信号。
2、添加IODELAY
上一节中通过VIO的方式确定下来一个比较好的时延值以后,就可以把该值固定下来固化使用了。不同的板子上使用的PHY芯片不同,都需要调试该时延值。代码中该时延值添加的代码如下:
上图中IDELAY_TYPE已经由上一节中的“VAR_LOADABLE”变为固定的“FIXED”,该FIXED值可以在XDC约束文件中配置使用。
验证及结果
在将参考时钟设置为125Mhz(一个tap125ps),CNTVALUEIN设置为16时,采样到正确的波形,使用TestCenter测试,千兆线速无丢包。
对于Altera(现在叫Intel)的FPGA,也可以采用SignalTAP里面的探针来动态的配置接口时延,来实现动态的调整RGMII接口数据与时钟相差四分之一相位的目的。不过,根据本人的经验,Xilinx的FPGA实现RGMII接口时序调整要比Altera的FPGA容易太多了。。。
以太网接口调试本公众号已经总结过一系列的文章了。常见的以太网接口调试方法可以见本公众号之前的文章,在此罗列几篇如下:
SGMII接口调试;
10G 以太网接口的FPGA实现,你需要的都在这里了
高速串行接口与GTXE_COMMON / GTXE_CHANNEL 问题汇总;
课堂演示实验二-基于FPGA的VGA控制电路设计;
课堂演示实验三-串口通信实验;
文章的结尾附上一个Xilinx 的K7 FPGA芯片做的背包挂坠,引领新时尚!
全文完。
*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。