Idelay对时序的补救

电子说

1.2w人已加入

描述

在高速信号采集的过程中,经常会因为电路设计或者其他原因,原本设计好对应的data_clk与data经过线路传输之后在接收端时序上不能很好的对应,这可能会造成采样数据的错位。

如果用了各种物理电路上的办法都没法解决后,可以尝试使用Idelay(针对Xilinx,Altera应该也有相应的原语)。

Xilinx每个系列可能Idelay的名字会有一些差异,但差异不大,在K7系列下,Idelay的原语叫做Idelay2。

Idelay2原语示例:

(* IODELAY_GROUP = "RX_FRAME" *) // Specifies group name for associated IDELAYs/ODELAYs and IDELAYCTRL
 IDELAYE2 #(
 .CINVCTRL_SEL("FALSE"), // Enable dynamic clock inversion (FALSE, TRUE)
 .DELAY_SRC("DATAIN"), // Delay input (IDATAIN, DATAIN)
 .HIGH_PERFORMANCE_MODE("FALSE"), // Reduced jitter ("TRUE"), Reduced power ("FALSE")
 .IDELAY_TYPE("VAR_LOAD"), // FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE
 .IDELAY_VALUE(INIT_VALUE), // Input delay tap setting (0-31)
 .PIPE_SEL("FALSE"), // Select pipelined mode, FALSE, TRUE
 .REFCLK_FREQUENCY(200.0), // IDELAYCTRL clock input frequency in MHz (190.0-210.0, 290.0-310.0).
 .SIGNAL_PATTERN("DATA") // DATA, CLOCK input signal
 )
 IDELAYE2_inst (
 .CNTVALUEOUT(cnt_value), // 5-bit output: Counter value output
 .DATAOUT(rx_frame_dly), // 1-bit output: Delayed data output
 .C(sys_clk), // 1-bit input: Clock input
 .CE(1'b0), // 1-bit input: Active high enable increment/decrement input
 .CINVCTRL(1'b0), // 1-bit input: Dynamic clock inversion input
 .CNTVALUEIN(tap_value), // 5-bit input: Counter value input
 .DATAIN(rx_frame), // 1-bit input: Internal delay data input
 .IDATAIN(1'b0), // 1-bit input: Data input from the I/O
 .INC(1'b0), // 1-bit input: Increment / Decrement tap delay input
 .LD(1'b1), // 1-bit input: Load IDELAY_VALUE input
 .LDPIPEEN(1'b0), // 1-bit input: Enable PIPELINE register to load data input
 .REGRST(1'b0) // 1-bit input: Active-high reset tap-delay input
 );

针对其中经常用到的变量,功能如下:

  • DELAY_SRC常量,这个常量可以选DATAIN或IDATAIN,区别在于IDATAIN的数据输入要求经过BUF产生,常用于BUF的输出信号,Input端口信号;DATAIN只要求FPGA内部逻辑产生的信号就可以。
  • IDELAY_TYPE,设置IDELAY2的模式;FIXED代表延时值固定,一般用在确定好参数后使用,VARIBLE,VAR_LOAD,VAR_LOAD_PIPE都是动态改变延时值,VARIBLE可以自动增大减小,后两个是根据CINVALUEIN端口动态改变延时值,一般选用VAR_LOAD。
  • IDELAY_VALUE,是初始化的值,在FIXED模式下,就是固定的延时值
  • REFCLK_FREQUENCY,指的Idelay的参考时钟的频率,一般选用200M,这个后面会具体讲。
  • SIGNAL_PATTERN,这个有DATA和CLOCK两个选项,影响Vivado对信号时序分析的路径。

端口中,

  • CNTVALUEIN是设置延时值,用于手动调试;
  • CNTVALUEOUT输出当前延时值,便于调试观测;
  • C是数据时钟,但CE不是时钟使能,而是延时值tap自动增加减少使能,所以我选择拉低;
  • CINVCTRL,INC,LDPIPEEIN,REGRST不怎么用,全拉低;
  • 在上面的DELAY_SRC选择了哪一个,就在对应的数据端口连接数据,另一个数据端口拉低,比如DELAY_SRC设定为"DATAIN",选择DATAIN端口输入数据,IDATAIN端口拉低;
  • 因为需要手动调节延时值,所以LD拉高,只有LD拉高才能动态载入CNTVALUEIN的延时值

前面说到参考时钟,Idelay之所以延时,CINVALUEIN对应的延时值多少就跟这个地方有关系了,参考时钟不是随便设的,这跟另一个原语IDELAYCTRL有关:

(* IODELAY_GROUP = "RX_FRAME" *) // Specifies group name for associated IDELAYs/ODELAYs and IDELAYCTRL
 IDELAYCTRL IDELAYCTRL_inst (
 .RDY(idelay_rdy), // 1-bit output: Ready output
 .REFCLK(ref_clk), // 1-bit input: Reference clock input
 .RST(rst) // 1-bit input: Active high reset input
 );

这个原语端口很少,连接对应200M的参考时钟,复位信号,输出一个ready信号;

看起来这个原语并没有什么有用的输出;但其实它的作用是给Idelay2提供了延时的依据;之所以可以精确延时并不是说我们在REFCLK_FREQUENCY填一个200就可以了,而是这个IDELAYCTRL 的作用,通过(* IODELAY_GROUP = "RX_FRAME" *)将IDELAYCTRL 和Idelay2连接起来,"RX_FRAME"类似于组名,可以随意改,同一组的组名要一样。

200MHz 对应1个时钟周期5ns,Idelay将其分为64tap,每个tap延时值大概是78ps,Idelay可调的最大tap为31,也就是延时值控制在0-31tap;

同样,为了减小相同参考时钟下Idelay2与IDELAYCTRL 的FPGA内部走线延时,必须使用IODELAY_GROUP将它们绑定在一起,使用方法参考上面的做法。

注意,IDELAYCTRL 的REFCLK输入时钟一定要经过BUFG输出再接入。

效果:

没加Idelay

串行通信

没有加Idelay,并串转换中找不到帧头

加入Idelay

串行通信

加了Idelay,找到帧头

总结:

  • 使用方法都在上面,对于多bit信号可以使用generate for 生成块。
  • 调试这个的时候遇到过一个问题,C端口没有连接到正常的时钟,连接到一个根本没有定义的信号,Vivado做好事不留名的直接帮我拉低到地,导致我在VAR_LOAD模式下一直无法正常改变延时值,CNTVALUEOUT与CINVALUEIN不正确,最后打开Schematic看RTL图才找到问题。
打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分