当前位置:   article > 正文

xilinx FPGA中oddr,idelay的用法详解

fpga的idelay

点击蓝字关注我们

  1. 关注、星标公众号,精彩内容每日送达
  2. 来源:网络素材

我们知道xilinx FPGA的selectio中有ilogic和ologic资源,可以实现iddr/oddr,idelay和odelay等功能。刚入门时可能对xilinx的原语不太熟练,在vivado的tools-> language templates中搜索iddr idelay等关键词,可以看到A7等器件下原语模板。复制出来照葫芦画瓢,再仿真一下基本就能学会怎么用了。

1. oddr

oddr和iddr都一样,以oddr为例,先去templates里把模板复制出来。

Add simulation source,建立一个简单的仿真文件。

  1. module simu_oddr(
  2.  
  3.     );
  4.         
  5.     reg clk = 1'd0;
  6.     always
  7.     forever #2 clk = ~ clk;
  8.        ODDR #(
  9.        .DDR_CLK_EDGE("OPPOSITE_EDGE"), // "OPPOSITE_EDGE" or "SAME_EDGE" 
  10.        .INIT(1'b0),    // Initial value of Q: 1'b0 or 1'b1
  11.        .SRTYPE("SYNC"// Set/Reset type: "SYNC" or "ASYNC" 
  12.     ) ODDR_inst (
  13.        .Q(Q),   // 1-bit DDR output
  14.        .C(clk),   // 1-bit clock input
  15.        .CE(1'd1), // 1-bit clock enable input
  16.        .D1(1'd1), // 1-bit data input (positive edge)
  17.        .D2(1'd0), // 1-bit data input (negative edge)
  18.        .R(1'd0),   // 1-bit reset
  19.        .S(1'd0)    // 1-bit set
  20.     );
  21.     
  22. endmodule

ODDR的使用方法在selectoi中的参考手册ug471中127页开始有说明,使用这些资源首先要参考的都是官方的资源手册。

6794fc59b39484215edd54f962f7fc4b.png

简单说明:

CE是使能,C是时钟,在时钟的上升沿下降沿分别输出D1和D2,Q是输出,S/R是复位,R = 1 Q输出0,S= 1,Q输出1,默认情况应该两个都等于0 ,两个都等于1时,输出0。"OPPOSITE_EDGE" or "SAME_EDGE" 手册中也有说明,指明采样时刻不同,具体有什么应用上区别我也不知道。

e2ba219f364e16081a186ecfc84a9c91.png

通过仿真,就可以看到输出是什么情况,在上升沿输出1,下降沿输出0,还可以看到输出有一点滞后。iddr和oddr在rgmii的接口中就可以方便地接收数据,转为gmii。一般情况要注意下时钟和数据的对齐问题,采样时钟可以相位往后一点,90° 1//4周期,输出的时候时钟也相应地滞后一点,就根据实际情况来,125M的DDR还是很容易采样稳定的。

2.idelay

在ug471告诉我们,只有hp bank才有odelay,在ug475中说明哪些系列有hp bank,简单说hp bank速度快很多,支持odelay,电压只能1.2V- 1.8V。其中A7全系是没有odelay的,K7才有(保留意见,简单看了一下),所以在language templates中搜索odelay是没有A系列的原语的。

1f8122a7c3d4142273bd9acd91507ddc.png 7d618e658f0925f09516c00cf5fc9b6c.png

idelay作用就是实现输入延迟,实际中应该有更明确的用法,这里只是我自己学习时的一些介绍。同样在ug471中对idelay也有介绍,有固定延时,可变延时,使用时都要例化idelay ctrl,延时的精度就可idelay ctrl的接入时钟有关。一个bank 只有1个idelay ctrl,同一个bank 要用idelay或者odelay,延时精度是一样的,虽然可以idelay ctrl可以接200Mhz,300Mhz,但同一个bank只能接1个,也只需要例化一次。多个bank要用idelay时,就要例化多次。

  1. `timescale 1ns / 1ps
  2.  
  3. module s(
  4.  
  5.     );
  6.     
  7.     reg clk = 1'd0;
  8.     always
  9.     forever #2.5 clk = ~ clk;
  10.     
  11.     
  12.      (* IODELAY_GROUP = "idelay" *)
  13.        IDELAYCTRL IDELAYCTRL_inst (
  14.        .RDY(),       // 1-bit output: Ready output
  15.        .REFCLK(clk), // 1-bit input: Reference clock input
  16.        .RST(1'd0)        // 1-bit input: Active high reset input
  17.     );
  18.  
  19.     
  20.     reg clk2 = 1'd0;
  21.     always @(posedge clk)
  22.         clk2 <= ~clk2;
  23.     
  24.     
  25.     wire DATAOUT;
  26.     
  27.        (* IODELAY_GROUP = "idelay" *) // Specifies group name for associated IDELAYs/ODELAYs and IDELAYCTRL
  28.     
  29.        IDELAYE2 #(
  30.           .CINVCTRL_SEL("FALSE"),          // Enable dynamic clock inversion (FALSE, TRUE)
  31.           .DELAY_SRC("IDATAIN"),           // Delay input (IDATAIN, DATAIN)
  32.           .HIGH_PERFORMANCE_MODE("FALSE"), // Reduced jitter ("TRUE"), Reduced power ("FALSE")
  33.           .IDELAY_TYPE("FIXED"),           // FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE
  34.           .IDELAY_VALUE(31),                // Input delay tap setting (0-31)
  35.           .PIPE_SEL("FALSE"),              // Select pipelined mode, FALSE, TRUE
  36.           .REFCLK_FREQUENCY(200.0),        // IDELAYCTRL clock input frequency in MHz (190.0-210.0, 290.0-310.0).
  37.           .SIGNAL_PATTERN("DATA")          // DATA, CLOCK input signal
  38.        )
  39.        IDELAYE2_inst (
  40.           .CNTVALUEOUT(CNTVALUEOUT), // 5-bit output: Counter value output
  41.           .DATAOUT(DATAOUT),         // 1-bit output: Delayed data output
  42.           .C(1'd1),                     // 1-bit input: Clock input
  43.           .CE(1'd0),                   // 1-bit input: Active high enable increment/decrement input
  44.           .CINVCTRL(1'd0),       // 1-bit input: Dynamic clock inversion input
  45.           .CNTVALUEIN(1'd0),   // 5-bit input: Counter value input
  46.           .DATAIN(1'd0),           // 1-bit input: Internal delay data input
  47.           .IDATAIN(clk2),         // 1-bit input: Data input from the I/O
  48.           .INC(1'd0),                 // 1-bit input: Increment / Decrement tap delay input
  49.           .LD(1'd0),                   // 1-bit input: Load IDELAY_VALUE input
  50.           .LDPIPEEN(1'd0),       // 1-bit input: Enable PIPELINE register to load data input
  51.           .REGRST(1'd0)            // 1-bit input: Active-high reset tap-delay input
  52.        );
  53.  
  54. endmodule

这里例化了一个idelay ctrl,是属于idelay group的,这个声明还没有研究过有什么用,不知道是不是指定idelay2和哪个ctrl是绑定的。idelay ctrl端口很简单,仿真时复位rst接0就好了,实际中推荐接输入时钟的pll lock引脚取反,保证在时钟锁定前(lock = 0)idelay ctrl处于复位状态。

idelay2中按推荐配置,从DATAIN还是从IDATAIN输入区别为是内部延时还是从IO输入,FIXED固定延时,idelay value先输入0,,时钟是200M,其他全部接0。此处,idelay的作用就是把IDATAIN的信号接入ilogic中,延时0个tap再从DATAOUT输出。可变延时的使用说明ug471上都有,还没学习,有需要了再去看。

idelay 有0-31个tap,分割200M的半个周期2.5ns,每个tap就是2.5ns/32 = 0.078125 ns

value = 0 可以看到输出延迟了0.6ns,value = 10时,延时了1.38ns。0.078125 * 10 + 0.6 = 1.38125,大体相近的。

其实oddr,idelay这些资源应该用起来都比较简单,可能我实际中就用了一下oddr/iddr,也没有觉得有多少难以调试的地方,本文简单介绍了这2个原语的使用方法,从复制原语,看手册介绍到仿真,其他原语也是类似的,学会如何去学习最重要。

文末再介绍一下generate,一样的在tools -> language templates中搜索。

  1. genvar;
  2.    generate
  3.       for (=0;<;=+1)
  4.       begin:
  5.          
  6.       end
  7.    endgenerate

用这个可以很方便地例化出多个相似的模块。

  1. genvar i; //genvar i;也可以定义到generate语句里面
  2.        generate
  3.               for(i=0;i<10;i=i+1)
  4.               begin:mymodule
  5.                      assign a[i]=reg[i];
  6.               end
  7.        endgenerate
666230a45f15350e6c212d149f5dcf07.jpeg

想要了解FPGA吗?这里有实例分享,ZYNQ设计,关注我们的公众号,探索

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

闽ICP备14008679号