Xilinx原语——IDDR与ODDR的使用(Ultrascale系列)

Xilinx原语——IDDR与ODDR的使用(Ultrascale系列)

  • 一、IDDR
    • 1.1 OPPOSITE_EDGE
    • 1.2 SAME_EDGE
    • 1.3 SAME_EDGE_PIPELINED
    • 1.4 三种模式异同
  • 二、ODDR
  • 三、IDDR与ODDR仿真
    • 3.1 IDDR仿真
      • 3.1.1 IDDR顶层
      • 3.1.2 TestBench
      • 3.1.3 仿真结果
    • 3.2 ODDR仿真
      • 3.2.1 ODDR顶层文件
      • 3.2.2 TestBench
      • 3.3.3 仿真结果

  对于各个系列的器件,IDDR与ODDR都存在一定的差别,在使用前需要根据自己的器件型号选择相应的IDDR与ODDR,下面以kintex ultrascale系列器件为例。

一、IDDR

  IDDR的输入输出引脚包括时钟输入C、时钟取反输入CB、数据输入D(在时钟信号C的上升沿与下降沿都发生变化)、异步复位R(高电平有效)与数据输出Q1和数据输出Q2。
Xilinx原语——IDDR与ODDR的使用(Ultrascale系列)_第1张图片
  IDDR的原语如下:

   IDDRE1 #(
      .DDR_CLK_EDGE("OPPOSITE_EDGE"), // IDDRE1 mode (OPPOSITE_EDGE, SAME_EDGE, SAME_EDGE_PIPELINED)
      .IS_CB_INVERTED(1'b0),          // Optional inversion for CB
      .IS_C_INVERTED(1'b0)            // Optional inversion for C
   )
   IDDRE1_inst (
      .Q1(Q1), // 1-bit output: Registered parallel output 1
      .Q2(Q2), // 1-bit output: Registered parallel output 2
      .C(C),   // 1-bit input: High-speed clock
      .CB(CB), // 1-bit input: Inversion of High-speed clock C
      .D(D),   // 1-bit input: Serial Data Input
      .R(R)    // 1-bit input: Active-High Async Reset
   );

  对于Kintex ultrascale的IDDRE1,有三种模式:OPPOSITE_EDGE、SAME_EDGE、 SAME_EDGE_PIPELINED,这三种模式下,输出信号Q1与Q2采样的数据分别是在时钟信号C的上升沿处的数据和下降沿处的数据,这是一致的。但是Q1与Q2发生变化的时间对于三种模式是有区别的。

1.1 OPPOSITE_EDGE

  在OPPOSITE_EDGE模式下,输出信号Q1在上升沿处对输入信号D进行采样,同时在该上升沿处Q1输出变为采样值;而输出信号Q2在下降沿处对输入信号D进行采样,同时在该下降沿处Q2输出变为采样值,如下图所示。
Xilinx原语——IDDR与ODDR的使用(Ultrascale系列)_第2张图片

1.2 SAME_EDGE

  在SAME_EDGE模式下,输出信号Q1与Q2发生变化的时间都是在上升沿处,但是不在同一个上升沿,两个变化的时间相差一个时钟周期。输出信号Q1在上升沿处对输入信号D进行采样,同时在该上升沿处Q1输出变为采样值;而输出信号Q2在下降沿处对输入信号D进行采样,同时在下一个上升沿沿处Q2输出变为采样值,如下图所示。
Xilinx原语——IDDR与ODDR的使用(Ultrascale系列)_第3张图片

1.3 SAME_EDGE_PIPELINED

  在SAME_EDGE_PIPELINED模式下,输出信号Q1与Q2发生变化的时间都是在上升沿处,而且在同一个上升沿。输出信号Q1在上升沿处对输入信号D进行采样,同时在下一个上升沿处Q1输出变为采样值;而输出信号Q2在下降沿处对输入信号D进行采样,同时在下一个上升沿沿处Q2输出变为采样值,如下图所示。
Xilinx原语——IDDR与ODDR的使用(Ultrascale系列)_第4张图片

1.4 三种模式异同

相同点 不同点
OPPOSITE_EDGE Q1采样的是上升沿处D的值,Q2采样的是下降沿处D的值 Q1与Q2数据发生变化是在不同的边沿,Q1数据发生变化是在采样的上升沿处,Q2数据发生变化是在采样的下降沿处
SAME_EDGE Q1采样的是上升沿处D的值,Q2采样的是下降沿处D的值 与OPPOSITE_EDGE 模式不同的是:Q1与Q2数据发生变化是在相同的边沿,但是相差一个时钟周期,Q1数据发生变化是在采样的上升沿处,Q2数据发生变化是在采样的下降沿的下一个上升沿
SAME_EDGE_PIPELINED Q1采样的是上升沿处D的值,Q2采样的是下降沿处D的值 Q1与Q2数据发生变化是在相同的边沿,与SAME_EDGE 模式不同的是:Q1与Q2变化发生在同一个上升沿,都是在下一个上升沿处

二、ODDR

  ODDR的输入输出引脚包括数据输入D1、数据输入D2、时钟信号C、异步复位信号SR(高电平有效)和数据输出Q(在时钟信号C的上升沿和下降沿均会发生变化)。
Xilinx原语——IDDR与ODDR的使用(Ultrascale系列)_第5张图片

  ODDR的原语如下:

   ODDRE1 #(
      .IS_C_INVERTED(1'b0),      // Optional inversion for C
      .IS_D1_INVERTED(1'b0),     // Unsupported, do not use
      .IS_D2_INVERTED(1'b0),     // Unsupported, do not use
      .SIM_DEVICE("ULTRASCALE"), // Set the device version for simulation functionality (ULTRASCALE)
      .SRVAL(1'b0)               // Initializes the ODDRE1 Flip-Flops to the specified value (1'b0, 1'b1)
   )
   ODDRE1_inst (
      .Q(Q),   // 1-bit output: Data output to IOB
      .C(C),   // 1-bit input: High-speed clock input
      .D1(D1), // 1-bit input: Parallel data input 1
      .D2(D2), // 1-bit input: Parallel data input 2
      .SR(SR)  // 1-bit input: Active-High Async Reset
   );

  与IDDR不同的是,ODDR只有一种模式——OPPOSITE_EDGE,在该模式下:数据输出Q在上升沿处的数据变为在上升沿处对输入数据D1的采样值,在下降沿处变为在上升沿处对输入数据D2的采样值,如下图所示。
Xilinx原语——IDDR与ODDR的使用(Ultrascale系列)_第6张图片

三、IDDR与ODDR仿真

3.1 IDDR仿真

3.1.1 IDDR顶层

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2023/06/05 20:10:15
// Design Name: 
// Module Name: iddr_top
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//

module iddr_top
(
    input         clk   ,
    input         rst   ,
    input         din   ,
    output        dout_1,
    output        dout_2

    );

wire  clk_opposite;

//  <-----Cut code below this line---->

   // IDDRE1: Dedicated Double Data Rate (DDR) Input Register
   //         Kintex UltraScale
   // Xilinx HDL Language Template, version 2021.1

   IDDRE1 #(
      .DDR_CLK_EDGE("SAME_EDGE_PIPELINED"), // IDDRE1 mode (OPPOSITE_EDGE, SAME_EDGE, SAME_EDGE_PIPELINED)
      .IS_CB_INVERTED(1'b0),          // Optional inversion for CB
      .IS_C_INVERTED(1'b0)            // Optional inversion for C
   )
   IDDRE1_inst (
      .Q1(dout_1), // 1-bit output: Registered parallel output 1
      .Q2(dout_2), // 1-bit output: Registered parallel output 2
      .C(clk),   // 1-bit input: High-speed clock
      .CB(clk_opposite), // 1-bit input: Inversion of High-speed clock C
      .D(din),   // 1-bit input: Serial Data Input
      .R(rst  )    // 1-bit input: Active-High Async Reset
   );

   // End of IDDRE1_inst instantiation

assign clk_opposite = ~clk;

endmodule

3.1.2 TestBench

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2023/06/05 20:17:59
// Design Name: 
// Module Name: tb_iddr_oddr
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//
module tb_iddr_oddr();
reg clk,rst;
reg  din;
wire dout_1,dout_2;

initial begin
    clk = 1'b1;
    rst <= 1'b1;
    #200 
    rst <= 1'b0;
    #10
    repeat(100) begin
        #5 
        din = {$random}%2;
        #5 
        din = {$random}%2;
    end

end

always #5 clk = ~clk;

iddr_top iddr_top_inst
(
    .clk   (clk   ),
    .rst (rst ),
    .din   (din   ),
    .dout_1(dout_1),
    .dout_2(dout_2)
);

endmodule

3.1.3 仿真结果

  分别对三种模式进行仿真,可以看到仿真结果与前面的理论结果一致。

(1)OPPOSITE_EDGE模式

Xilinx原语——IDDR与ODDR的使用(Ultrascale系列)_第7张图片
(2)SAME_EDGE模式

Xilinx原语——IDDR与ODDR的使用(Ultrascale系列)_第8张图片
(3)SAME_EDGE_PIPELINED模式

Xilinx原语——IDDR与ODDR的使用(Ultrascale系列)_第9张图片

3.2 ODDR仿真

3.2.1 ODDR顶层文件

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2023/06/05 20:10:29
// Design Name: 
// Module Name: oddr_top
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//

module oddr_top(
    input         clk   ,
    input         rst   ,
    input         din_1 ,
    input         din_2 ,
    output        dout   
);

//   ODDRE1    : In order to incorporate this function into the design,
//   Verilog   : the following instance declaration needs to be placed
//  instance   : in the body of the design code.  The instance name
// declaration : (ODDRE1_inst) and/or the port declarations within the
//    code     : parenthesis may be changed to properly reference and
//             : connect this function to the design.  All inputs
//             : and outputs must be connected.

//  <-----Cut code below this line---->

   // ODDRE1: Dedicated Double Data Rate (DDR) Output Register
   //         Kintex UltraScale
   // Xilinx HDL Language Template, version 2021.1

   ODDRE1 #(
      .IS_C_INVERTED(1'b0),      // Optional inversion for C
      .IS_D1_INVERTED(1'b0),     // Unsupported, do not use
      .IS_D2_INVERTED(1'b0),     // Unsupported, do not use
      .SIM_DEVICE("ULTRASCALE"), // Set the device version for simulation functionality (ULTRASCALE)
      .SRVAL(1'b0)               // Initializes the ODDRE1 Flip-Flops to the specified value (1'b0, 1'b1)
   )
   ODDRE1_inst (
      .Q(dout),   // 1-bit output: Data output to IOB
      .C(clk),   // 1-bit input: High-speed clock input
      .D1(din_1), // 1-bit input: Parallel data input 1
      .D2(din_2), // 1-bit input: Parallel data input 2
      .SR(rst  )  // 1-bit input: Active-High Async Reset
   );

   // End of ODDRE1_inst instantiation
					
endmodule

3.2.2 TestBench

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2023/06/05 20:17:59
// Design Name: 
// Module Name: tb_iddr_oddr
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//

module tb_iddr_oddr();
reg clk,rst;
reg  din_1,din_2;
wire dout;

initial begin
    clk = 1'b1;
    rst <= 1'b1;
    #200 
    rst <= 1'b0;
    #12
    repeat(100) begin
        #10 
        din_1 = {$random}%2;
        din_2 = {$random}%2;
    end

end

always #5 clk = ~clk;

oddr_top oddr_top_inst
(
    .clk  (clk  ),
    .rst  (rst  ),
    .din_1(din_1),
    .din_2(din_2),
    .dout (dout ) 
);

endmodule

3.3.3 仿真结果

  对ODDR进行仿真,可以看到仿真结果与前面的理论结果一致。在上升沿处,输出dout与上上升沿处输入din_1的值一致;在下降沿处,输出dout与上升沿处输入din_2的值一致。

Xilinx原语——IDDR与ODDR的使用(Ultrascale系列)_第10张图片

你可能感兴趣的:(Xilinx原语,fpga开发,Xilinx原语,Verilog)