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。
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输出变为采样值,如下图所示。
1.2 SAME_EDGE
在SAME_EDGE模式下,输出信号Q1与Q2发生变化的时间都是在上升沿处,但是不在同一个上升沿,两个变化的时间相差一个时钟周期。输出信号Q1在上升沿处对输入信号D进行采样,同时在该上升沿处Q1输出变为采样值;而输出信号Q2在下降沿处对输入信号D进行采样,同时在下一个上升沿沿处Q2输出变为采样值,如下图所示。
1.3 SAME_EDGE_PIPELINED
在SAME_EDGE_PIPELINED模式下,输出信号Q1与Q2发生变化的时间都是在上升沿处,而且在同一个上升沿。输出信号Q1在上升沿处对输入信号D进行采样,同时在下一个上升沿处Q1输出变为采样值;而输出信号Q2在下降沿处对输入信号D进行采样,同时在下一个上升沿沿处Q2输出变为采样值,如下图所示。
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的上升沿和下降沿均会发生变化)。
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的采样值,如下图所示。
三、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.1IDDRE1 #(.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 instantiationassign 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 beginclk = 1'b1;rst <= 1'b1;#200 rst <= 1'b0;#10repeat(100) begin#5 din = {$random}%2;#5 din = {$random}%2;endendalways #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模式
(2)SAME_EDGE模式
(3)SAME_EDGE_PIPELINED模式
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.1ODDRE1 #(.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 instantiationendmodule
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 beginclk = 1'b1;rst <= 1'b1;#200 rst <= 1'b0;#12repeat(100) begin#10 din_1 = {$random}%2;din_2 = {$random}%2;endendalways #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的值一致。