当前位置:   article > 正文

Xilinx IDELAYE2应用笔记及仿真实操_idelaye2使用

idelaye2使用

文章目录


一、为什么要学习IDELAYE2

  两个器件进行通讯时,至少都需要一个数据线来传输数据,并且还需要满足一定的时序才能保证数据准确的传输。像UART、SPI、IIC等传输频率并不高,布线的传输延时可忽略不计,只要满足相应的协议就可实现数据的传输,当然这种情况只限外部干扰较小的情况,如果要确保传输的准确性,还需要进行校验。但在高速传输时,在硬件上通过差分传输来降低外界的干扰信号,但数据线的长短会影响传输的时长。如通过clk和data两对差分线进行传输,由于clk的布线与dara的布线存在长短上的差异,主机传输到从机后clk和data的延时各不相同。如果我们希望在时钟上升沿上采集数据,但由于线的延时,可能在时钟上升沿时数据处于变化状态,这将会导致采集的数据错误。通过IDELAYE2原语可将某根信号线进行延时操作,以达到在时钟上升沿数据处于稳定的操作。

  本文章是作者学习LVDS时的学习笔记,主要参考UG471和PG070。

二、IDELAYE2原语

  上图为IDELAYE2例化框图,首先对IDELAYE2做个系统的介绍。

  IDELAYE2是Xilinx内部的输入信号延时资源,它主要是把输入信号延时一段时间。IDELAYE2可以一共有四个工作模式:固定延迟模式(FIXED), 可变延迟模式(VARIABLE), 可加载可变延迟模式(VAR_LOAD或VAR_LOAD_PIPE),VAR_LOAD与VAR_LOAD_PIPE模式相识,只是加载的位置不同,下文会进行阐述。

1.IDELAYE2端口说明

2.IDELAYE2属性说明

3.IDELAYE2的延时计算

  IDELAY2是一个可编程的31阶延迟原语,通过改变tap的值可以改变数据线的延时大小,其延时的分辨率与参考时钟频率f有关,延时的分辨率delay_resolution计算公式如下:

                      delay_resolution = 1/(32 * 2 * f)*1000000(ps)

其中f单位为Mhz。

  当f=200Mhz时,delay_resolution=78ps(注:计算出来为78.125ps,但会取整,为78ps);

  同样,当f=300Mhz时,delay_resolution=52ps。

延时的具体大小计算如下:

  1.当tap=0时,我们要弄清一个误区,tap=0时并不是延时就是0,此时delay_time=600ps;

  2.当tap!=0时,delay_time=600ps + tap * delay_resolution。

4.IDELAYE2模式

1.固定延迟模式(IDELAY_TPYE=FIXED)

  在该模式下数据延迟由属性IDELAY_VALUE设置,且延迟固定,不可更改。在该模式下,IDELAYCTRL原语必须例化。

2.可变延迟模式(IDELAY_TPYE=VARIABLE)

  在该模式下,延迟值可以在配置后通过CE和INC端口进行动态配置。同样,在该模式下,IDELAYCTRL原语也必须例化。该模式下的逻辑控制对应关系如下表所示。

3.可加载可变延迟模式(IDELAY_TYPE=VAR_LOAD)

  该模式下功能与VARIABLE模式下类似,只不过可以通过CNTVALUEIN加载延迟节拍数。多了一种延迟加载方法。当LD端口有效时可以加载新的延迟CNTVALUE值到控制模块。该模式下逻辑功能关系如下表所示。

5.IDELAYE2时序

1.可变延迟模式(IDELAY_TPYE=VARIABLE)

  下图为可变模式下的延迟时序图。

  参考前文可变延迟模式下的逻辑表,可见1时刻C=1,LD=1,CE=0,INC=0,则会加载IDELAY_VALUE的值到tap上,即此时tap0=IDELAY_VALUE;在时刻2时,C=1,LD=0,CE=1,INC=1,tap的值会自动累加1,即tap1=IDELAY_VALUE + 1;在时刻3时,C=1,LD=0,CE=0,INC=0,tap的值不变,即tap1=IDELAY_VALUE + 1;

2.可加载可变延迟模式(IDELAY_TYPE=VAR_LOAD)

  参考前文可加载可变延迟模式下的逻辑表,可见1时刻C=1,LD=1,INC=0,CE=0,CNTVALUEIN=5’b00010,则会加载CNTVALUEIN的值到tap上,即tap=5‘b00010;在2时刻C=1,LD=0,INC=1,CE=1,CNTVALUEIN=5’b01010,则此时tap的值会自动加1,即tap=5‘b00010 + 1’b1 = 5‘b00011;在3时刻,C=1,LD=1,INC=0,CE=0,CNTVALUEIN=5’b01010,则会加载CNTVALUEIN的值到tap上,即tap=5‘b01010;

三、IDELAYCTRL原语

  上图为IDELAYCTRL例化框图。 如果IDELAYE2或ODELAYE2原语被实例化,那么IDELAYCTRL模块也必须被实例化。IDELAYCTRL模块在其区域内连续校准单个延迟点(iddelay /ODELAY),以减少过程、电压和温度变化的影响。IDELAYCTRL模块使用用户提供的REFCLK校准IDELAY和ODELAY。

1.IDELAYCTRL端口说明

2.IDELAYCTRL时序

  在IDELAYCTRL原语复位后要经过TIDELAYCTRLCO_RDY时间后RDY才被拉高,但若参考时钟在多个时钟周期内保持了不变,RDY就会拉低,此时IDELAYCTRL需要重新复位。

四、IDELAYE2工程代码

1.工程代码

  1. `timescale 1ns /1ps
  2. module idelay_test(
  3. input clk_in_50,
  4. input reset,
  5. input[4:0] in_delay_tap_in_int,
  6. input in_delay_ce,
  7. input data_in_from_pins_int,
  8. input in_delay_inc_dec,
  9. input LD,
  10. output delay_locked,
  11. output[4:0] in_delay_tap_out_int,
  12. output data_in_from_pins_delay
  13. );
  14. wire ref_clock_bufg;
  15. wire ref_clock;
  16. wire io_reset;
  17. wire clk_200 ;
  18. wire clk_100 ;
  19. wire clk_50 ;
  20. wire clk_25 ;
  21. wire locked ;
  22. assign ref_clock = clk_200;
  23. assign io_reset = locked ? reset:1'b1;
  24. assign clk_div_in = clk_50;
  25. clk_wiz_0
  26. clk_wiz_0_inst(
  27. .clk_200m (clk_200 ),
  28. .clk_100m (clk_100 ),
  29. .clk_50m (clk_50 ),
  30. .clk_25m (clk_25 ),
  31. .reset (reset ),
  32. .locked (locked),
  33. .clk_in1 (clk_in_50));
  34. // (* IODELAY_GROUP = <iodelay_group_test> *) // Specifies group name for associated IDELAYs/ODELAYs and IDELAYCTRL
  35. IDELAYE2 #(.CINVCTRL_SEL("FALSE"), // Enable dynamic clock inversion (FALSE, TRUE).DELAY_SRC("IDATAIN"), // Delay input (IDATAIN, DATAIN).HIGH_PERFORMANCE_MODE("TRUE"), // Reduced jitter ("TRUE"), Reduced power ("FALSE").IDELAY_TYPE("FIXED"), // FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE.IDELAY_VALUE(0), // 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(in_delay_tap_out_int), // 5-bit output: Counter value output.DATAOUT(data_in_from_pins_delay),// 1-bit output: Delayed data output.C(clk_div_in), // 1-bit input: Clock input.CE(in_delay_ce), // 1-bit input: Active high enable increment/decrement input.CINVCTRL(1'b0), // 1-bit input: Dynamic clock inversion input.CNTVALUEIN(in_delay_tap_in_int), // 5-bit input: Counter value input.DATAIN(1'b0), // 1-bit input: Internal delay data input.IDATAIN(data_in_from_pins_int), // 1-bit input: Data input from the I/O.INC(in_delay_inc_dec), // 1-bit input: Increment / Decrement tap delay input.LD(LD), // 1-bit input: Load IDELAY_VALUE input.LDPIPEEN(1'b0), // 1-bit input: Enable PIPELINE register to load data input.REGRST(io_reset) // 1-bit input: Active-high reset tap-delay input);
  36. // (* IODELAY_GROUP = <iodelay_group_test> *) // Specifies group name for associated IDELAYs/ODELAYs and IDELAYCTRL
  37. IDELAYCTRL IDELAYCTRL_inst(.RDY(delay_locked), // 1-bit output: Ready output.REFCLK(ref_clock_bufg), // 1-bit input: Reference clock input.RST(io_reset) // 1-bit input: Active high reset input);
  38. BUFG
  39. ref_clk_bufg(.I(ref_clock),.O(ref_clock_bufg));
  40. endmodule
  41. 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182

2.测试代码

  1. `timescale 1ns /1ps
  2. module idelay_test_tb();
  3. reg clk_in_50 ;
  4. reg reset ;
  5. reg LD ;
  6. reg in_delay_ce ;
  7. reg in_delay_inc_dec ;
  8. wire delay_locked ;
  9. reg[4:0] in_delay_tap_in_int ;
  10. wire[4:0] in_delay_tap_out_int ;
  11. reg data_in_from_pins_int ;
  12. wire data_in_from_pins_delay ;
  13. `define clk_period 20
  14. `define clk_div_in_period 20
  15. idelay_test
  16. idelay_test_utt(
  17. .clk_in_50 (clk_in_50 ),
  18. .reset(reset ),
  19. .in_delay_tap_in_int(in_delay_tap_in_int ),
  20. .in_delay_ce(in_delay_ce ),
  21. .data_in_from_pins_int(data_in_from_pins_int ),
  22. .in_delay_inc_dec(in_delay_inc_dec ),
  23. .LD(LD ),
  24. .delay_locked(delay_locked ),
  25. .in_delay_tap_out_int(in_delay_tap_out_int ),
  26. .data_in_from_pins_delay(data_in_from_pins_delay ));
  27. initial begin clk_in_50 =0; end
  28. always #(`clk_period/2) clk_in_50=~clk_in_50;
  29. initial begin
  30. // FIXED_task;
  31. // VARIABLE_task;
  32. VAR_LOAD_task;
  33. $stop;
  34. end
  35. task init;
  36. begin
  37. reset =1;
  38. in_delay_tap_in_int =0;
  39. in_delay_ce =0;
  40. data_in_from_pins_int =0;
  41. in_delay_inc_dec =0;
  42. LD =0;
  43. #(`clk_div_in_period*10+1);
  44. reset =0;
  45. @(posedge idelay_test_utt.locked);
  46. #(`clk_div_in_period*5);
  47. end
  48. endtask
  49. task FIXED_task;
  50. begin
  51. init;
  52. data_in_from_pins_int =1;
  53. #(`clk_div_in_period*10);
  54. end
  55. endtask
  56. task VARIABLE_task;
  57. begin
  58. init;
  59. repeat(3)begin
  60. /*******tap自加1********/
  61. in_delay_ce =1;
  62. in_delay_inc_dec =1;
  63. #(`clk_div_in_period*1);
  64. in_delay_ce =0;
  65. in_delay_inc_dec =0;
  66. data_in_from_pins_int =~data_in_from_pins_int;
  67. /*********END************/
  68. #(`clk_div_in_period*1000);
  69. end
  70. /**加载CNTVALUEIN到tap中*/
  71. LD =1;
  72. #(`clk_div_in_period*1);
  73. LD =0;
  74. data_in_from_pins_int =~data_in_from_pins_int;
  75. #(`clk_div_in_period*1000);
  76. /*********END************/
  77. repeat(3)begin
  78. /*******tap自减1********/
  79. in_delay_ce =1;
  80. in_delay_inc_dec =0;
  81. #(`clk_div_in_period*1);
  82. in_delay_ce =0;
  83. in_delay_inc_dec =0;
  84. data_in_from_pins_int =~data_in_from_pins_int;
  85. /*********END************/
  86. #(`clk_div_in_period*1000);
  87. end
  88. /**加载CNTVALUEIN到tap中*/
  89. LD =1;
  90. #(`clk_div_in_period*1);
  91. LD =0;
  92. data_in_from_pins_int =~data_in_from_pins_int;
  93. #(`clk_div_in_period*1000);
  94. /*********END************/
  95. end
  96. endtask
  97. task VAR_LOAD_task;
  98. begin
  99. init;
  100. /*******CNTVALUEIN task********/
  101. in_delay_tap_in_int =10;
  102. #(`clk_div_in_period*5);
  103. LD =1;
  104. #(`clk_div_in_period*1);
  105. LD =0;
  106. data_in_from_pins_int =~data_in_from_pins_int;
  107. #(`clk_div_in_period*1000);
  108. /*********END************/
  109. repeat(3)begin
  110. /*******tap自加1********/
  111. in_delay_ce =1;
  112. in_delay_inc_dec =1;
  113. #(`clk_div_in_period*1);
  114. in_delay_ce =0;
  115. in_delay_inc_dec =0;
  116. data_in_from_pins_int =~data_in_from_pins_int;
  117. /*********END************/
  118. #(`clk_div_in_period*1000);
  119. end
  120. /*******CNTVALUEIN task********/
  121. in_delay_tap_in_int =15;
  122. #(`clk_div_in_period*5);
  123. LD =1;
  124. #(`clk_div_in_period*1);
  125. LD =0;
  126. data_in_from_pins_int =~data_in_from_pins_int;
  127. #(`clk_div_in_period*1000);
  128. /*********END************/
  129. end
  130. endtask
  131. endmodule
  132. 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150

注:在进行仿真时需要将IDELAY_TYPE修改为对应的模式。

五、IDELAYE2仿真

1.FIXED模式

  当IDELAY_TYPE = FIXED为FIXED模式,线的延时时间由IDELAY_VALUE来确定。

首先当IDELAY_VALUE = 0时,仿真结果如下:

可见,线延时了600ps。

当IDELAY_VALUE = 1时,仿真结果如下:

可见,线延时了(600 + 78)ps = 678ps。

当IDELAY_VALUE = 31时,仿真结果如下:

可见,线延时了(600 + 78*31)ps = 3018ps。

2.VARIABLE模式

延时大小为(600 + 78*13)ps = 3018ps。

可见延时的大小按照上述执行。

3.VAR_LOAD模式

延时大小为(600 + 78*15)ps = 1770ps。

可见延时的大小按照上述执行。

六、总结

  本文针对IDELAYE2原语进行详解,阐明了延时的最小分辨率与参考时钟有关,分辨率为delay_resolution = 1/(322f)*1000000(ps)。通过编写测试代码,对IDELAYE2的FIXED模式、VARIABLE模式及VAR_LOAD模式进行了仿真,结果与UG471一致。

七、附录

工程文件

https://download.csdn.net/download/weixin_45372778/66985301

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/614431
推荐阅读
相关标签
  

闽ICP备14008679号