@@ -33,19 +33,15 @@ THE SOFTWARE.
3333 */
3434module iddr #
3535(
36- // target ("SIM", "GENERIC", "XILINX", "ALTERA")
37- parameter TARGET = "GENERIC" ,
38- // IODDR style ("IODDR", "IODDR2")
39- // Use IODDR for Virtex-4, Virtex-5, Virtex-6, 7 Series, Ultrascale
40- // Use IODDR2 for Spartan-6
41- parameter IODDR_STYLE = "IODDR2" ,
4236 // Width of register in bits
4337 parameter WIDTH = 1 ,
44- parameter INSERT_BUFFERS = "FALSE"
38+ parameter INSERT_BUFFERS = "FALSE" ,
39+ // Can be count or time depending on delay type
40+ parameter [8 :0 ] DELAY_VALUE = 9'h19
4541)
4642(
4743 input wire clk,
48-
44+ // Data input
4945 input wire [WIDTH- 1 :0 ] d,
5046
5147 output wire [WIDTH- 1 :0 ] q1,
@@ -66,6 +62,8 @@ Provides a consistent input DDR flip flop across multiple FPGA families
6662
6763*/
6864wire [WIDTH- 1 :0 ] d_int;
65+ wire [WIDTH- 1 :0 ] delayed_data_int;
66+
6967genvar n;
7068
7169generate
@@ -81,83 +79,50 @@ end else begin
8179 assign d_int = d;
8280end
8381
84- if (TARGET == "XILINX" ) begin
85- for (n = 0 ; n < WIDTH; n = n + 1 ) begin : iddr
86- if (IODDR_STYLE == "IODDR" ) begin
87- IDDR #(
88- .DDR_CLK_EDGE("SAME_EDGE_PIPELINED" ),
89- .SRTYPE("ASYNC" )
90- )
91- iddr_inst (
92- .Q1(q1[n]),
93- .Q2(q2[n]),
94- .C(clk),
95- .CE(1'b1 ),
96- .D(d_int[n]),
97- .R(1'b0 ),
98- .S(1'b0 )
99- );
100- end else if (IODDR_STYLE == "IODDR2" ) begin
101- wire q1_int;
102- reg q1_delay;
103-
104- IDDR2 #(
105- .DDR_ALIGNMENT("C0" )
106- )
107- iddr_inst (
108- .Q0(q1_int),
109- .Q1(q2[n]),
110- .C0(clk),
111- .C1(~clk),
112- .CE(1'b1 ),
113- .D(d_int[n]),
114- .R(1'b0 ),
115- .S(1'b0 )
116- );
117-
118- always @(posedge clk) begin
119- q1_delay <= q1_int;
120- end
121-
122- assign q1[n] = q1_delay;
123- end
124- end
125- end else if (TARGET == "ALTERA" ) begin
126- wire [WIDTH- 1 :0 ] q1_int;
127- reg [WIDTH- 1 :0 ] q1_delay;
128-
129- altddio_in #(
130- .WIDTH(WIDTH),
131- .POWER_UP_HIGH("OFF" )
82+ for (n = 0 ; n < WIDTH; n = n + 1 ) begin : iddr
83+ // Use IDELAYE3 for Ultrascale and Ultrascale+ devices to adjust delay between clock and data
84+ // found delay count value by sweeping and checking the output
85+ IDELAYE3 #(
86+ .CASCADE("NONE" ),
87+ .DELAY_FORMAT("COUNT" ), // Units of the DELAY_VALUE (COUNT, TIME)
88+ .DELAY_SRC("IDATAIN" ),
89+ .DELAY_TYPE("FIXED" ),
90+ .DELAY_VALUE(9'h19 ),
91+ .IS_CLK_INVERTED(1'b0 ),
92+ .IS_RST_INVERTED(1'b0 ),
93+ .REFCLK_FREQUENCY(300 .0 ),
94+ .SIM_DEVICE("ULTRASCALE_PLUS" ),
95+ .UPDATE_MODE("ASYNC" )
13296 )
133- altddio_in_inst (
134- .aset(1'b0 ),
135- .datain(d_int),
136- .inclocken(1'b1 ),
137- .inclock(clk),
138- .aclr(1'b0 ),
139- .dataout_h(q1_int),
140- .dataout_l(q2)
97+ IDELAYE3_inst (
98+ .CASC_OUT(),
99+ .CNTVALUEOUT(),
100+ .DATAOUT(delayed_data_int[n]),
101+ .CASC_IN(0 ),
102+ .CASC_RETURN(0 ),
103+ .CE(0 ),
104+ .CLK(clk),
105+ .CNTVALUEIN(0 ),
106+ .DATAIN(0 ),
107+ .EN_VTC(0 ),
108+ .IDATAIN(d_int[n]),
109+ .INC(0 ),
110+ .LOAD(0 ),
111+ .RST(0 )
141112 );
142-
143- always @(posedge clk) begin
144- q1_delay <= q1_int;
145- end
146-
147- assign q1 = q1_delay;
148- end else begin
113+ end
149114 reg [WIDTH- 1 :0 ] d_reg_1 = {WIDTH{1'b0 }};
150115 reg [WIDTH- 1 :0 ] d_reg_2 = {WIDTH{1'b0 }};
151116
152117 reg [WIDTH- 1 :0 ] q_reg_1 = {WIDTH{1'b0 }};
153118 reg [WIDTH- 1 :0 ] q_reg_2 = {WIDTH{1'b0 }};
154119
155120 always @(posedge clk) begin
156- d_reg_1 <= d_int ;
121+ d_reg_1 <= delayed_data_int ;
157122 end
158123
159124 always @(negedge clk) begin
160- d_reg_2 <= d_int ;
125+ d_reg_2 <= delayed_data_int ;
161126 end
162127
163128 always @(posedge clk) begin
@@ -167,7 +132,6 @@ end else begin
167132
168133 assign q1 = q_reg_1;
169134 assign q2 = q_reg_2;
170- end
171135
172136endgenerate
173137
0 commit comments