IDDR、ODDR、IDEALY2和ODELAY2详解

前言

本文参考XILINX手册UG471

一、IDDR原语

参考xilinx手册UG471

    IDDR #(
        .DDR_CLK_EDGE   ("SAME_EDGE_PIPELINED"    ),
        .INIT_Q1        (1'b0                     ),
        .INIT_Q2        (1'b0                     ),
        .SRTYPE         ("SYNC"                   ) 
    )   
    IDDR_u0     
    (   
        .Q1             (w_rec_data[rxd_i]          ), // 1-bit output for positive edge of clock 
        .Q2             (w_rec_data[rxd_i +4]       ), // 1-bit output for negative edge of clock
        .C              (w_rxc_bufio                ),  
        .CE             (1                          ),
        .D              (w_rxd_idly[rxd_i]          ),  
        .R              (0                          ),   
        .S              (0                          )   
    );

在数据的传输过程中,我们经常可以碰见双沿传输数据到FPGA,或者FPGA传输双沿数据给外部芯片,最常见的例子就是DDR芯片。这里说明一下,FPGA内部处理的数据都是单沿数据,那么双沿数据的变换只能发生在FPGA的IOB上面,这里有特定的硬件结构可以实现上面单沿变双沿的方法,也就是使用原语进行一些列的操作。
D:为输入的双倍速率的数据,即D在时钟的上升沿和下降沿都会发生切换,一个时钟周期发送2bit数据,
CE:为时钟使能信号
C:为时钟信号
S,R:为复位和置位信号
Q1,Q2:为单倍速率的输出数据
IDDR主要有三种工作模式,分别是:OPPOSITE_EDGE, SAME_EDGESAME_EDGE_PIPELINED ,代码里采用的是第三种方式。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

二、ODDR原语

ODDR #(
    .DDR_CLK_EDGE    ("OPPOSITE_EDGE"       ),
    .INIT            (1'b0                  ),
    .SRTYPE          ("SYNC"                ) 
) 
ODDR_u 
(
    .Q               (o_txd[txd_i]          ),  
    .C               (w_txc                 ),
    .CE              (1                     ),
    .D1              (w_send_d1[txd_i]      ),    
    .D2              (w_send_d2[txd_i]      ),    
    .R               (0                     ),
    .S               (0                     ) 
);

接口与IDDR一致,就是输入输出相反而已,有OPPOSITE_EDGE模式和SAME_EDGE俩种方式,代码里采用OPPOSITE_EDGE模式
在这里插入图片描述
在这里插入图片描述

三、IDELAYCTRL原语

IDELAYCTRL其实是个辅助模块,只要咱们使用了IDELAY或者ODELAY,IDELAYCTRL必须被使用,要不然就无法正常工作。因为IDELAY或者ODELAY的延迟精度是由IDELAYCTRL的输入时钟决定的,它会不断矫正IDELAY2和ODELAY2,将误差限制在一定范围,一般为200MHz。

(* IODELAY_GROUP = "rgmii_rx_delay" *) 
IDELAYCTRL  IDELAYCTRL_inst (
    .RDY(),                      // 1-bit output: Ready output
    .REFCLK(idelay_clk),         // 1-bit input: Reference clock input
    .RST(1'b0)                   // 1-bit input: Active high reset input
);

在这里插入图片描述

四、IDELAY原语

IDELAY被称为信号延迟模块,它的作用就是把信号延迟一段时间。对于一些需要对齐的输入信号来说,这至关重要。在7系列FPGA中,它被称为IDELAYE2。IDELAYE2可以将信号延迟0~31节,在这区间任意可调,并且在参考时钟为200M时,每节的延迟精度为78ps(1/(32×2×FREF),FREF为IDELAYCTRL的参考时钟)。

(* IODELAY_GROUP = "rgmii" *)
IDELAYE2 #(
   .CINVCTRL_SEL            ("FALSE"        ),          // Enable dynamic clock inversion (FALSE, TRUE)
   .DELAY_SRC               ("IDATAIN"      ),           // Delay input (IDATAIN, DATAIN)
   .HIGH_PERFORMANCE_MODE   ("FALSE"        ), // 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) 0.15625
   .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             (), // 5-bit output: Counter value output
   .DATAOUT                 (w_rxc_idelay   ),         // 1-bit output: Delayed data output
   .C                       (),                     // 1-bit input: Clock input
   .CE                      (),                   // 1-bit input: Active high enable increment/decrement input
   .CINVCTRL                (),       // 1-bit input: Dynamic clock inversion input
   .CNTVALUEIN              (),   // 5-bit input: Counter value input
   .DATAIN                  (),           // 1-bit input: Internal delay data input
   .IDATAIN                 (i_rxc          ),         // 1-bit input: Data input from the I/O
   .INC                     (),                 // 1-bit input: Increment / Decrement tap delay input
   .LD                      (),                   // 1-bit input: Load IDELAY_VALUE input
   .LDPIPEEN                (),       // 1-bit input: Enable PIPELINE register to load data input
   .REGRST                  ()            // 1-bit input: Active-high reset tap-delay input
);

在这里插入图片描述

4.1、参数配置 :

  1. IDELAY_TYPE:有四种模式FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE,默认为FIXED。
    FIXED:固定的延迟值,设置静态的延时参数0-31,如:IDELAY_VALUE = 25,表示延时为25级,一旦配置后续无法更改
    VAR_LOAD:动态加载tap值,该模式下使用LD装载输入端将CNTVALUEIN的值载入,使用CE和NC实现加减1,与时钟同步
    在这里插入图片描述

VARIABLE:动态调节延时值,由输入管脚值决定,与时钟C同步
在这里插入图片描述

VAR_LOAD_PIPE: 与VAR_LOAD模式类似,并CNTVALUEIN值

  1. DELAY_SRCIDATAIN:输入数据来自IBUF,DATAIN:输入数据来自FPGA逻辑。
  2. HIGH_PERFORMANCE_MODE:TRUE: 减少输出抖动,但会增加功耗
  3. IDELAY_VALUE :在FXED模式,指定延时级数taps;在VARIABLE模式下的初始值,即加载的tap初始值;另外两种模式自动忽略,不使用,置0
  4. SIGNAL_PATTERN :输入信号是数据还是时钟
  5. REFCLK_FREQUENCY :参考时钟,确定每个延时tap的精度;200M时,1个tap=78ps
  6. CINVCTRL_SEL :使能CINVCTRL_SEL管脚来动态切换输入时钟的极性。
  7. PIPE_SEL :选择pipeline模式,只用于VAR_LOAD_PIPE模式

4.2、端口说明 :

  1. C : 时钟输入,用于VARIABLE, VAR_LOAD, VAR_LOAD_PIPE模式
  2. REGRST : Pipeline寄存器的复位,只用于VAR_LOAD_PIPE 模式。
  3. LD : 在VARIABLE 模式,加在IDELAYE2延时的值IDELAY_VALUE;在VAR_LOAD模式下,将输入CNTVALUEIN装载,LD,CD,INC配合使用
  4. CE :使能增加/减少的功能
  5. INC :增加或减少tap delays数量
  6. CINVCTRL :动态转换时钟极性,时钟极性改变后,至少延迟俩个时钟才稳定
  7. CNTVALUEIN :接收FPGA内部逻辑用于动态装载延迟级数,用于VAR_LOAD模式
  8. IDATAIN :输入数据来自IBUF
  9. DATAIN : 输入数据来自FPGA逻辑
  10. LDPIPEEN :使能流水线寄存器装载到DELAY2的延迟级数值,只在VAR_LOAD_PIPE有效
  11. DATAOUT : 延迟后的数据输出
  12. CNTVALUEOUT :实际延迟级数taps输出,用于FPGA内部监测

4.3、延时控制时序图

1、VARIABLE模式时序图

  • 时钟1:时钟C上升沿检测到延迟级数复位(LD为高),加载IDELAY_VALUE,即输出延时为tap0.
  • 时钟2:时钟C上升沿检测到CE和INC为高,即增加一级延时,输出延时变为tap1
  • 时钟3:此时全部为0,输出延时保持不变,直到下一次检测到LD、CE和INC。

在这里插入图片描述
2、VAR_LOAD模式时序图

  • 时钟0:LD、CE和INC都为低,无事发生
  • 时钟1:检测到LD,此时加载用户输入的CNTVALUEIN 5’b00010,即输出延时级数为tap2
  • 时钟2:INC和CE为高,输出延时级数加1变为tap3
  • 时钟3,有一次检测到LD,在此加载用户输入CNTVALUEIN,此时输入为5b01010,即tap10
    在这里插入图片描述

五、ODELAY原语

ODELAY和IDEALY的使用方式差不多,只不过ODELAY是用作输出信号的延迟。另外,HR BANK内没有ODELAY,HP BANK才有,被称为ODELAYE2。使用ODELAYE2时同样需要例化IDELAYCTRL。
在这里插入图片描述

  • 19
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
ODDR是Vivado中的一个IP核,用于在FPGA设计中实现双数据率输出。ODDR的作用是将输入数据根据时钟信号的边缘进行采样,并将采样到的数据输出到输出端口。 在Vivado中使用ODDR时,需要注意一些问题。首先,ODDR的输出必须直接连到输出PAD上,不能再引进逻辑内部。如果将ODDR的输出连入逻辑内部,会导致输出无法正常连入到OLOGIC中。 此外,在使用ODDR时,还需要注意时钟信号的边缘敏感性。根据所使用IDDR的特性,需要确保时钟信号的边缘与IDDR的时钟边缘一致,以正确采样输入数据并输出。 另外,可以使用BUFGMUX来选择不同的时钟信号,以满足不同的时钟要求。BUFGMUX可以帮助实现时钟信号的切换,以适应不同的设计需求。 总之,ODDR是在Vivado中用于实现双数据率输出的IP核,使用时需要注意输出直接连到输出PAD上,使用合适的时钟信号边缘敏感性以及可以使用BUFGMUX实现时钟信号的切换。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [FPGA原语IODELAY、ODDR、BUFGMUX和VIVADO BRAM的使用](https://blog.csdn.net/leixj025/article/details/122666017)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

顺子学不会FPGA

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值