前言

Xilinx原语IDDR的功能就是将双沿采样的数据转换为单沿数据,然后再传输给FPGA内部进行使用。

一、IDDR的三种模式

IDDR的原语框图如下图所示。
在这里插入图片描述
IDDR的工作模式主要有以下三种,可通过配置原语中的DDR_CLK_EDGE参数进行控制。
1.1 OPPOSITE_EDGE模式
该模式对应的时序图如下,其中C是时钟信号,CE是时钟使能信号,D是输入数据,由图可知D在C的上升沿和下降沿都有数据变化的,即双沿传输。
在这里插入图片描述
Q1和Q2是输出数据,Q1在时钟上升沿输出在时钟上升沿采集到的数据,而Q2在时钟下降沿数据发生变化,用于输出在时钟下降沿时采集到的数据。
1.2 SAME_EDGE模式
SAME_EDGE模式与OPPOSITE_EDGE模式的区别在于,SAME_EDGE模式的Q1和Q2只会在时钟C的上升沿输出数据。
在这里插入图片描述
第一个时钟上升沿之后,Q1输出采集到的D0A,由于此时还没有经过下降沿,Q1输出无效数据。在第一个下降沿,Q2采集D的数据,在第二个时钟上升沿之后,Q1输出采集第二个时钟上升沿采集的数据D2A,Q2输出第一个时钟下降沿采集的数据D1A。
上述两种方式都不是最常用的模式,最常用的数据采集模式SAME_EDGE_PIPELINED模式
1.3 SAME_EDGE_PIPELINED模式
下图显示了使用SAME_EDGE_PIPELINED模式的IDDR的时序图,Q1和Q2同时提供给FPGA逻辑,更方便用户使用。
在这里插入图片描述
与SAME_EDGE模式类似,SAME_EDGE_PIPELINED只是将Q1输出数据延迟一个时钟周期,让Q1和Q2的第一个数据至最后一个数据进行对齐,方便后续操作,唯一的差别是是Q1输出数据延迟了一个时钟周期

二、IDDR原语使用

2.1 IDDR原语参数介绍

IDDR原语的几个参数如下表所示:
在这里插入图片描述

2.2 IDDR原语获取

在vivado中获取原语模板的方法下图所示,在Tools选项卡下点击Language Templates。
在这里插入图片描述
搜索框搜索想要的原语模块名,此处为IDDR,然后选择对应器件下的对应原语,此处使用K7-325T,即K7。右侧为IDDR原语对应的例化模板,赋值到代码中使用即可。
在这里插入图片描述
IDDR原语模板:

IDDR #(
      .DDR_CLK_EDGE("OPPOSITE_EDGE"), // "OPPOSITE_EDGE", "SAME_EDGE" 
                                      //    or "SAME_EDGE_PIPELINED" 
      .INIT_Q1(1'b0), // Initial value of Q1: 1'b0 or 1'b1
      .INIT_Q2(1'b0), // Initial value of Q2: 1'b0 or 1'b1
      .SRTYPE("SYNC") // Set/Reset type: "SYNC" or "ASYNC" 
   ) IDDR_inst (
      .Q1(Q1), // 1-bit output for positive edge of clock
      .Q2(Q2), // 1-bit output for negative edge of clock
      .C(C),   // 1-bit clock input
      .CE(CE), // 1-bit clock enable input
      .D(D),   // 1-bit DDR data input
      .R(R),   // 1-bit reset
      .S(S)    // 1-bit set
   );

2.3 代码设计

代码如下(示例):

module iddr_ctrl(
   input       clk      ,//系统时钟信号;
   input       rst      ,//系统复位信号,高电平有效;

   input       clk_en   ,//时钟使能信号;
   input       din      ,//输入数据;
   output      dout1    ,//输出数据
   output      dout2    
); 
   reg         clk_en_r ;
   //(* IOB = "TRUE" *)reg clk_en_r ;//将clk_en_r放在ILOGICE中;

   //将clk_en打拍,用于验证IOB原语是否有效;
   always@(posedge clk)begin
      clk_en_r <= clk_en;
   end

   //例化IDDR原语
   IDDR #(
      .DDR_CLK_EDGE  ("SAME_EDGE_PIPELINED"  ),// "OPPOSITE_EDGE", "SAME_EDGE" or "SAME_EDGE_PIPELINED" 
      .INIT_Q1       (1'b0                   ),// Initial value of Q1: 1'b0 or 1'b1
      .INIT_Q2       (1'b0                   ),// Initial value of Q2: 1'b0 or 1'b1
      .SRTYPE        ("SYNC"                 ) // Set/Reset type: "SYNC" or "ASYNC" 
   ) 
   IDDR_inst (
      .Q1   (dout1   ),// 1-bit output for positive edge of clock
      .Q2   (dout2   ),// 1-bit output for negative edge of clock
      .C    (clk     ),// 1-bit clock input
      .CE   (clk_en_r),// 1-bit clock enable input
      .D    (din     ),// 1-bit DDR data input
      .R    (rst     ),// 1-bit reset
      .S    (1'b0    ) // 1-bit set
   );

endmodule

总结

以上就是今天要讲的内容,本文仅仅简单介绍了IDDR的使用,感兴趣的同学们可以把三种模式都进行仿真试试。

Logo

纵情码海钱塘涌,杭州开发者创新动! 属于杭州的开发者社区!致力于为杭州地区的开发者提供学习、合作和成长的机会;同时也为企业交流招聘提供舞台!

更多推荐