1 //*****************************************************************************
2 // (c) Copyright 2009 - 2013 Xilinx, Inc. All rights reserved.
4 // This file contains confidential and proprietary information
5 // of Xilinx, Inc. and is protected under U.S. and
6 // international copyright and other intellectual property
10 // This disclaimer is not a license and does not grant any
11 // rights to the materials distributed herewith. Except as
12 // otherwise provided in a valid license issued to you by
13 // Xilinx, and to the maximum extent permitted by applicable
14 // law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
15 // WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
16 // AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
17 // BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
18 // INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
19 // (2) Xilinx shall not be liable (whether in contract or tort,
20 // including negligence, or under any other theory of
21 // liability) for any loss or damage of any kind or nature
22 // related to, arising under or in connection with these
23 // materials, including for any direct, or any indirect,
24 // special, incidental, or consequential loss or damage
25 // (including loss of data, profits, goodwill, or any type of
26 // loss or damage suffered as a result of any action brought
27 // by a third party) even if such damage or loss was
28 // reasonably foreseeable or Xilinx had been advised of the
29 // possibility of the same.
31 // CRITICAL APPLICATIONS
32 // Xilinx products are not designed or intended to be fail-
33 // safe, or for use in any application requiring fail-safe
34 // performance, such as life-support or safety devices or
35 // systems, Class III medical devices, nuclear facilities,
36 // applications related to the deployment of airbags, or any
37 // other applications that could lead to death, personal
38 // injury, or severe property or environmental damage
39 // (individually and collectively, "Critical
40 // Applications"). Customer assumes the sole risk and
41 // liability of any use of Xilinx products in Critical
42 // Applications, subject only to applicable laws and
43 // regulations governing limitations on product liability.
45 // THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
46 // PART OF THIS FILE AT ALL TIMES.
48 //*****************************************************************************
51 // /___/ \ / Vendor: Xilinx
52 // \ \ \/ Version: %version
53 // \ \ Application: MIG
54 // / / Filename: ddr_phy_oclkdelay_cal.v
55 // /___/ /\ Date Last Modified: $Date: 2011/02/25 02:07:40 $
56 // \ \ / \ Date Created: Aug 03 2009
60 //Design Name: DDR3 SDRAM
61 //Purpose: Center write DQS in write DQ valid window using Phaser_Out Stage3
65 //*****************************************************************************
73 parameter nCK_PER_CLK =
4,
74 parameter DRAM_TYPE =
"DDR3",
75 parameter DRAM_WIDTH =
8,
76 parameter DQS_CNT_WIDTH =
3,
77 parameter DQS_WIDTH =
8,
78 parameter DQ_WIDTH =
64,
79 parameter SIM_CAL_OPTION =
"NONE",
80 parameter OCAL_EN =
"ON"
85 // Start only after PO and PI FINE delay decremented
86 input oclk_init_delay_start,
87 input oclkdelay_calib_start,
88 input [
5:
0]
oclkdelay_init_val,
89 // Detect write valid data edge during OCLKDELAY calib
91 input [
2*
nCK_PER_CLK*
DQ_WIDTH-
1:
0]
rd_data,
92 // Precharge done status from ddr_phy_init
94 // Write Level signals during OCLKDELAY calibration
95 input [
6*
DQS_WIDTH-
1:
0]
wl_po_fine_cnt,
96 output reg wrlvl_final,
97 // Inc/dec Phaser_Out fine delay line
98 output reg po_stg3_incdec,
99 output reg po_en_stg3,
100 output reg po_stg23_sel,
101 output reg po_stg23_incdec,
102 output reg po_en_stg23,
103 // Completed initial delay increment
104 output oclk_init_delay_done,
105 output [
DQS_CNT_WIDTH:
0]
oclkdelay_calib_cnt,
106 output reg oclk_prech_req,
107 output reg oclk_calib_resume,
108 output oclkdelay_calib_done,
109 output [
255:
0]
dbg_phy_oclkdelay_cal,
110 output [
16*
DRAM_WIDTH-
1:
0]
dbg_oclkdelay_rd_data
114 // Start with an initial delay of 0 on OCLKDELAY. This is required to
115 // detect two valid data edges when possible. Two edges cannot be
116 // detected if write DQ and DQS are exactly edge aligned at stage3 tap0.
117 localparam TAP_CNT =
0;
118 //(tCK <= 938) ? 13 :
119 //(tCK <= 1072) ? 14 :
120 //(tCK <= 1250) ? 15 :
121 //(tCK <= 1500) ? 16 : 17;
123 localparam WAIT_CNT =
15;
124 // Default set to TRUE because there can be a case where the ocal_rise_right_edge
125 // may not be detected if WRLVL stage2 tap value is large upto 63 and the initial
126 // DQS position is more than 225 degrees
127 localparam MINUS_32 =
"TRUE";
129 localparam [
4:
0]
OCAL_IDLE =
5'h00;
130 localparam [
4:
0]
OCAL_NEW_DQS_WAIT =
5'h01;
131 localparam [
4:
0]
OCAL_STG3_SEL =
5'h02;
132 localparam [
4:
0]
OCAL_STG3_SEL_WAIT =
5'h03;
133 localparam [
4:
0]
OCAL_STG3_EN_WAIT =
5'h04;
134 localparam [
4:
0]
OCAL_STG3_DEC =
5'h05;
135 localparam [
4:
0]
OCAL_STG3_WAIT =
5'h06;
136 localparam [
4:
0]
OCAL_STG3_CALC =
5'h07;
137 localparam [
4:
0]
OCAL_STG3_INC =
5'h08;
138 localparam [
4:
0]
OCAL_STG3_INC_WAIT =
5'h09;
139 localparam [
4:
0]
OCAL_STG2_SEL =
5'h0A;
140 localparam [
4:
0]
OCAL_STG2_WAIT =
5'h0B;
141 localparam [
4:
0]
OCAL_STG2_INC =
5'h0C;
142 localparam [
4:
0]
OCAL_STG2_DEC =
5'h0D;
143 localparam [
4:
0]
OCAL_STG2_DEC_WAIT =
5'h0E;
144 localparam [
4:
0]
OCAL_NEXT_DQS =
5'h0F;
145 localparam [
4:
0]
OCAL_NEW_DQS_READ =
5'h10;
146 localparam [
4:
0]
OCAL_INC_DONE_WAIT =
5'h11;
147 localparam [
4:
0]
OCAL_STG3_DEC_WAIT =
5'h12;
148 localparam [
4:
0]
OCAL_DEC_DONE_WAIT =
5'h13;
149 localparam [
4:
0]
OCAL_DONE =
5'h14;
154 reg oclk_init_delay_start_r;
161 reg [
5:
0]
delay_cnt_r;
164 wire [
DQ_WIDTH-
1:
0]
rd_data_rise0;
165 wire [
DQ_WIDTH-
1:
0]
rd_data_fall0;
166 wire [
DQ_WIDTH-
1:
0]
rd_data_rise1;
167 wire [
DQ_WIDTH-
1:
0]
rd_data_fall1;
168 wire [
DQ_WIDTH-
1:
0]
rd_data_rise2;
169 wire [
DQ_WIDTH-
1:
0]
rd_data_fall2;
170 wire [
DQ_WIDTH-
1:
0]
rd_data_rise3;
171 wire [
DQ_WIDTH-
1:
0]
rd_data_fall3;
173 reg [
DQS_CNT_WIDTH:
0]
cnt_dqs_r;
174 reg [
DQS_CNT_WIDTH:
0]
mux_sel_r;
175 reg [
DRAM_WIDTH-
1:
0]
sel_rd_rise0_r;
176 reg [
DRAM_WIDTH-
1:
0]
sel_rd_fall0_r;
177 reg [
DRAM_WIDTH-
1:
0]
sel_rd_rise1_r;
178 reg [
DRAM_WIDTH-
1:
0]
sel_rd_fall1_r;
179 reg [
DRAM_WIDTH-
1:
0]
sel_rd_rise2_r;
180 reg [
DRAM_WIDTH-
1:
0]
sel_rd_fall2_r;
181 reg [
DRAM_WIDTH-
1:
0]
sel_rd_rise3_r;
182 reg [
DRAM_WIDTH-
1:
0]
sel_rd_fall3_r;
183 reg [
DRAM_WIDTH-
1:
0]
prev_rd_rise0_r;
184 reg [
DRAM_WIDTH-
1:
0]
prev_rd_fall0_r;
185 reg [
DRAM_WIDTH-
1:
0]
prev_rd_rise1_r;
186 reg [
DRAM_WIDTH-
1:
0]
prev_rd_fall1_r;
187 reg [
DRAM_WIDTH-
1:
0]
prev_rd_rise2_r;
188 reg [
DRAM_WIDTH-
1:
0]
prev_rd_fall2_r;
189 reg [
DRAM_WIDTH-
1:
0]
prev_rd_rise3_r;
190 reg [
DRAM_WIDTH-
1:
0]
prev_rd_fall3_r;
196 reg [
DRAM_WIDTH-
1:
0]
pat_match_fall0_r;
197 reg pat_match_fall0_and_r;
198 reg [
DRAM_WIDTH-
1:
0]
pat_match_fall1_r;
199 reg pat_match_fall1_and_r;
200 reg [
DRAM_WIDTH-
1:
0]
pat_match_fall2_r;
201 reg pat_match_fall2_and_r;
202 reg [
DRAM_WIDTH-
1:
0]
pat_match_fall3_r;
203 reg pat_match_fall3_and_r;
204 reg [
DRAM_WIDTH-
1:
0]
pat_match_rise0_r;
205 reg pat_match_rise0_and_r;
206 reg [
DRAM_WIDTH-
1:
0]
pat_match_rise1_r;
207 reg pat_match_rise1_and_r;
208 reg [
DRAM_WIDTH-
1:
0]
pat_match_rise2_r;
209 reg pat_match_rise2_and_r;
210 reg [
DRAM_WIDTH-
1:
0]
pat_match_rise3_r;
211 reg pat_match_rise3_and_r;
212 reg pat_data_match_r;
213 reg pat_data_match_valid_r;
214 reg pat_data_match_valid_r1;
215 //reg [3:0] stable_stg3_cnt;
217 reg [
3:
0]
stable_rise_stg3_cnt;
218 reg stable_rise_eye_r;
219 reg [
3:
0]
stable_fall_stg3_cnt;
220 reg stable_fall_eye_r;
222 reg [
3:
0]
wait_cnt_r;
224 reg oclkdelay_calib_start_r;
225 reg [
5:
0]
stg3_tap_cnt;
226 reg [
5:
0]
stg3_incdec_limit;
228 reg [
5:
0]
stg2_tap_cnt;
229 reg [
1:
0]
stg2_inc2_cnt;
230 reg [
1:
0]
stg2_dec2_cnt;
231 reg [
5:
0]
stg2_dec_cnt;
234 reg [
4:
0]
ocal_state_r;
235 reg [
4:
0]
ocal_state_r1;
236 reg [
5:
0]
ocal_final_cnt_r;
237 reg ocal_final_cnt_r_calc;
238 reg [
5:
0]
ocal_inc_cnt;
239 reg [
5:
0]
ocal_dec_cnt;
240 reg ocal_stg3_inc_en;
241 reg ocal_rise_edge1_found;
242 reg ocal_rise_edge2_found;
243 reg ocal_rise_edge1_found_timing;
244 reg ocal_rise_edge2_found_timing;
245 reg [
5:
0]
ocal_rise_edge1_taps;
246 reg [
5:
0]
ocal_rise_edge2_taps;
247 reg [
5:
0]
ocal_rise_right_edge;
248 reg ocal_fall_edge1_found;
249 reg ocal_fall_edge2_found;
250 reg [
5:
0]
ocal_fall_edge1_taps;
251 reg [
5:
0]
ocal_fall_edge2_taps;
252 reg [
5:
0]
ocal_final_cnt_r_mux_a;
253 reg [
5:
0]
ocal_final_cnt_r_mux_b;
254 reg [
5:
0]
ocal_final_cnt_r_mux_c;
255 reg [
5:
0]
ocal_final_cnt_r_mux_d;
258 reg ocal_wrlvl_done_r;
259 (*
keep =
"true",
max_fanout =
10 *)
reg ocal_done_r /* synthesis syn_maxfan = 10 **/;
260 reg [
5:
0]
ocal_tap_cnt_r[
0:
DQS_WIDTH-
1];
265 reg stg3_tap_cnt_eq_oclkdelay_init_val;
266 reg stg3_tap_cnt_eq_0;
267 //reg stg3_tap_cnt_gt_20;
268 reg stg3_tap_cnt_eq_63;
269 reg stg3_tap_cnt_less_oclkdelay_init_val;
271 wire [
5:
0]
wl_po_fine_cnt_w[
0:
DQS_WIDTH-
1];
273 //**************************************************************************
275 //**************************************************************************
279 for (
dqs_i=
0;
dqs_i <
DQS_WIDTH;
dqs_i =
dqs_i +
1)
begin:
oclkdelay_tap_cnt
280 assign dbg_phy_oclkdelay_cal[
6*
dqs_i+:
6] =
ocal_tap_cnt_r[
dqs_i][
5:
0];
284 assign dbg_phy_oclkdelay_cal[
57:
54] =
cnt_dqs_r;
285 assign dbg_phy_oclkdelay_cal[
58] =
ocal_rise_edge1_found_timing;
286 assign dbg_phy_oclkdelay_cal[
59] =
ocal_rise_edge2_found_timing;
287 assign dbg_phy_oclkdelay_cal[
65:
60] =
ocal_rise_edge1_taps;
288 assign dbg_phy_oclkdelay_cal[
71:
66] =
ocal_rise_edge2_taps;
289 assign dbg_phy_oclkdelay_cal[
76:
72] =
ocal_state_r1;
290 assign dbg_phy_oclkdelay_cal[
77] =
pat_data_match_valid_r;
291 assign dbg_phy_oclkdelay_cal[
78] =
pat_data_match_r;
292 assign dbg_phy_oclkdelay_cal[
84:
79] =
stg3_tap_cnt;
293 assign dbg_phy_oclkdelay_cal[
88:
85] =
stable_rise_stg3_cnt;
294 assign dbg_phy_oclkdelay_cal[
89] =
stable_rise_eye_r;
295 assign dbg_phy_oclkdelay_cal[
97:
90] =
prev_rd_rise0_r;
296 assign dbg_phy_oclkdelay_cal[
105:
98] =
prev_rd_fall0_r;
297 assign dbg_phy_oclkdelay_cal[
113:
106] =
prev_rd_rise1_r;
298 assign dbg_phy_oclkdelay_cal[
121:
114] =
prev_rd_fall1_r;
299 assign dbg_phy_oclkdelay_cal[
129:
122] =
prev_rd_rise2_r;
300 assign dbg_phy_oclkdelay_cal[
137:
130] =
prev_rd_fall2_r;
301 assign dbg_phy_oclkdelay_cal[
145:
138] =
prev_rd_rise3_r;
302 assign dbg_phy_oclkdelay_cal[
153:
146] =
prev_rd_fall3_r;
303 assign dbg_phy_oclkdelay_cal[
154] =
rd_active_r;
304 assign dbg_phy_oclkdelay_cal[
162:
155] =
sel_rd_rise0_r;
305 assign dbg_phy_oclkdelay_cal[
170:
163] =
sel_rd_fall0_r;
306 assign dbg_phy_oclkdelay_cal[
178:
171] =
sel_rd_rise1_r;
307 assign dbg_phy_oclkdelay_cal[
186:
179] =
sel_rd_fall1_r;
308 assign dbg_phy_oclkdelay_cal[
194:
187] =
sel_rd_rise2_r;
309 assign dbg_phy_oclkdelay_cal[
202:
195] =
sel_rd_fall2_r;
310 assign dbg_phy_oclkdelay_cal[
210:
203] =
sel_rd_rise3_r;
311 assign dbg_phy_oclkdelay_cal[
218:
211] =
sel_rd_fall3_r;
312 assign dbg_phy_oclkdelay_cal[
219+:
6] =
stg2_tap_cnt;
313 assign dbg_phy_oclkdelay_cal[
225] =
ocal_fall_edge1_found;
314 assign dbg_phy_oclkdelay_cal[
226] =
ocal_fall_edge2_found;
315 assign dbg_phy_oclkdelay_cal[
232:
227] =
ocal_fall_edge1_taps;
316 assign dbg_phy_oclkdelay_cal[
238:
233] =
ocal_fall_edge2_taps;
317 assign dbg_phy_oclkdelay_cal[
244:
239] =
ocal_rise_right_edge;
318 assign dbg_phy_oclkdelay_cal[
250:
245] =
'd0;
319 assign dbg_phy_oclkdelay_cal[
251] =
stable_fall_eye_r;
320 assign dbg_phy_oclkdelay_cal[
252] =
rise_win;
321 assign dbg_phy_oclkdelay_cal[
253] =
fall_win;
323 assign dbg_oclkdelay_rd_data[
DRAM_WIDTH*
1 -
1:
0] =
prev_rd_rise0_r;
324 assign dbg_oclkdelay_rd_data[
DRAM_WIDTH*
2 -
1:
DRAM_WIDTH*
1] =
prev_rd_fall0_r;
325 assign dbg_oclkdelay_rd_data[
DRAM_WIDTH*
3 -
1:
DRAM_WIDTH*
2] =
prev_rd_rise1_r;
326 assign dbg_oclkdelay_rd_data[
DRAM_WIDTH*
4 -
1:
DRAM_WIDTH*
3] =
prev_rd_fall1_r;
327 assign dbg_oclkdelay_rd_data[
DRAM_WIDTH*
5 -
1:
DRAM_WIDTH*
4] =
prev_rd_rise2_r;
328 assign dbg_oclkdelay_rd_data[
DRAM_WIDTH*
6 -
1:
DRAM_WIDTH*
5] =
prev_rd_fall2_r;
329 assign dbg_oclkdelay_rd_data[
DRAM_WIDTH*
7 -
1:
DRAM_WIDTH*
6] =
prev_rd_rise3_r;
330 assign dbg_oclkdelay_rd_data[
DRAM_WIDTH*
8 -
1:
DRAM_WIDTH*
7] =
prev_rd_fall3_r;
331 assign dbg_oclkdelay_rd_data[
DRAM_WIDTH*
9 -
1:
DRAM_WIDTH*
8] =
sel_rd_rise0_r;
332 assign dbg_oclkdelay_rd_data[
DRAM_WIDTH*
10 -
1:
DRAM_WIDTH*
9] =
sel_rd_fall0_r;
333 assign dbg_oclkdelay_rd_data[
DRAM_WIDTH*
11 -
1:
DRAM_WIDTH*
10] =
sel_rd_rise1_r;
334 assign dbg_oclkdelay_rd_data[
DRAM_WIDTH*
12 -
1:
DRAM_WIDTH*
11] =
sel_rd_fall1_r;
335 assign dbg_oclkdelay_rd_data[
DRAM_WIDTH*
13 -
1:
DRAM_WIDTH*
12] =
sel_rd_rise2_r;
336 assign dbg_oclkdelay_rd_data[
DRAM_WIDTH*
14 -
1:
DRAM_WIDTH*
13] =
sel_rd_fall2_r;
337 assign dbg_oclkdelay_rd_data[
DRAM_WIDTH*
15 -
1:
DRAM_WIDTH*
14] =
sel_rd_rise3_r;
338 assign dbg_oclkdelay_rd_data[
DRAM_WIDTH*
16 -
1:
DRAM_WIDTH*
15] =
sel_rd_fall3_r;
340 assign oclk_init_delay_done = ((
SIM_CAL_OPTION ==
"FAST_CAL") || (
DRAM_TYPE!=
"DDR3")) ?
1'b1 :
delay_done_r4;
//(SIM_CAL_OPTION != "NONE")
341 assign oclkdelay_calib_cnt =
cnt_dqs_r;
342 assign oclkdelay_calib_done = (
OCAL_EN ==
"ON") ?
ocal_done_r :
1'b1;
344 always @(
posedge clk)
345 oclk_init_delay_start_r <= #TCQ
oclk_init_delay_start;
347 always @(
posedge clk)
begin
348 if (
rst ||
po_stg3_dec)
349 count <= #TCQ
WAIT_CNT;
350 else if (
oclk_init_delay_start && (
count >
'd0))
351 count <= #TCQ
count -
1;
354 always @(
posedge clk)
begin
356 po_stg3_dec <= #TCQ
1'b0;
357 else if ((
count ==
'd1) && (
delay_cnt_r !=
'd0))
358 po_stg3_dec <= #TCQ
1'b1;
360 po_stg3_dec <= #TCQ
1'b0;
363 //po_stg3_incdec and po_en_stg3 asserted for all data byte lanes
364 always @(
posedge clk)
begin
366 po_stg3_incdec <= #TCQ
1'b0;
367 po_en_stg3 <= #TCQ
1'b0;
368 end else if (
po_stg3_dec)
begin
369 po_stg3_incdec <= #TCQ
1'b0;
370 po_en_stg3 <= #TCQ
1'b1;
372 po_stg3_incdec <= #TCQ
1'b0;
373 po_en_stg3 <= #TCQ
1'b0;
377 // delay counter to count TAP_CNT cycles
378 always @(
posedge clk)
begin
379 // load delay counter with init value of TAP_CNT
381 delay_cnt_r <= #TCQ
TAP_CNT;
382 else if (
po_stg3_dec && (
delay_cnt_r >
6'd0))
383 delay_cnt_r <= #TCQ
delay_cnt_r -
1;
386 // when all the ctl_lanes have their output phase shifted by 1/4 cycle, delay shifting is done.
387 always @(
posedge clk)
begin
389 delay_done <= #TCQ
1'b0;
390 end else if ((
TAP_CNT ==
6'd0) || ((
delay_cnt_r ==
6'd1) &&
391 (
count ==
'd1)))
begin
392 delay_done <= #TCQ
1'b1;
396 always @(
posedge clk)
begin
397 delay_done_r1 <= #TCQ
delay_done;
398 delay_done_r2 <= #TCQ
delay_done_r1;
399 delay_done_r3 <= #TCQ
delay_done_r2;
400 delay_done_r4 <= #TCQ
delay_done_r3;
403 //**************************************************************************
404 // OCLKDELAY Calibration
405 //**************************************************************************
408 if (
nCK_PER_CLK ==
4)
begin:
gen_rd_data_div4
409 assign rd_data_rise0 =
rd_data[
DQ_WIDTH-
1:
0];
410 assign rd_data_fall0 =
rd_data[
2*
DQ_WIDTH-
1:
DQ_WIDTH];
411 assign rd_data_rise1 =
rd_data[
3*
DQ_WIDTH-
1:
2*
DQ_WIDTH];
412 assign rd_data_fall1 =
rd_data[
4*
DQ_WIDTH-
1:
3*
DQ_WIDTH];
413 assign rd_data_rise2 =
rd_data[
5*
DQ_WIDTH-
1:
4*
DQ_WIDTH];
414 assign rd_data_fall2 =
rd_data[
6*
DQ_WIDTH-
1:
5*
DQ_WIDTH];
415 assign rd_data_rise3 =
rd_data[
7*
DQ_WIDTH-
1:
6*
DQ_WIDTH];
416 assign rd_data_fall3 =
rd_data[
8*
DQ_WIDTH-
1:
7*
DQ_WIDTH];
417 end else if (
nCK_PER_CLK ==
2)
begin:
gen_rd_data_div2
418 assign rd_data_rise0 =
rd_data[
DQ_WIDTH-
1:
0];
419 assign rd_data_fall0 =
rd_data[
2*
DQ_WIDTH-
1:
DQ_WIDTH];
420 assign rd_data_rise1 =
rd_data[
3*
DQ_WIDTH-
1:
2*
DQ_WIDTH];
421 assign rd_data_fall1 =
rd_data[
4*
DQ_WIDTH-
1:
3*
DQ_WIDTH];
426 always @(
posedge clk)
begin
427 mux_sel_r <= #TCQ
cnt_dqs_r;
428 oclkdelay_calib_start_r <= #TCQ
oclkdelay_calib_start;
429 ocal_wrlvl_done_r <= #TCQ
ocal_wrlvl_done;
430 rd_active_r <= #TCQ
phy_rddata_en;
431 rd_active_r1 <= #TCQ
rd_active_r;
432 rd_active_r2 <= #TCQ
rd_active_r1;
433 rd_active_r3 <= #TCQ
rd_active_r2;
434 rd_active_r4 <= #TCQ
rd_active_r3;
435 stg3_dec_r <= #TCQ
stg3_dec;
436 ocal_state_r1 <= #TCQ
ocal_state_r;
441 // Register outputs for improved timing.
442 // All bits in selected DQS group are checked in aggregate
445 for (
mux_j =
0;
mux_j <
DRAM_WIDTH;
mux_j =
mux_j +
1)
begin:
gen_mux_rd
446 always @(
posedge clk)
begin
447 if (
phy_rddata_en)
begin
448 sel_rd_rise0_r[
mux_j] <= #TCQ
rd_data_rise0[
DRAM_WIDTH*
mux_sel_r +
mux_j];
449 sel_rd_fall0_r[
mux_j] <= #TCQ
rd_data_fall0[
DRAM_WIDTH*
mux_sel_r +
mux_j];
450 sel_rd_rise1_r[
mux_j] <= #TCQ
rd_data_rise1[
DRAM_WIDTH*
mux_sel_r +
mux_j];
451 sel_rd_fall1_r[
mux_j] <= #TCQ
rd_data_fall1[
DRAM_WIDTH*
mux_sel_r +
mux_j];
452 sel_rd_rise2_r[
mux_j] <= #TCQ
rd_data_rise2[
DRAM_WIDTH*
mux_sel_r +
mux_j];
453 sel_rd_fall2_r[
mux_j] <= #TCQ
rd_data_fall2[
DRAM_WIDTH*
mux_sel_r +
mux_j];
454 sel_rd_rise3_r[
mux_j] <= #TCQ
rd_data_rise3[
DRAM_WIDTH*
mux_sel_r +
mux_j];
455 sel_rd_fall3_r[
mux_j] <= #TCQ
rd_data_fall3[
DRAM_WIDTH*
mux_sel_r +
mux_j];
461 always @(
posedge clk)
462 if (((
stg3_tap_cnt_eq_oclkdelay_init_val) &&
rd_active_r) |
464 prev_rd_rise0_r <= #TCQ
sel_rd_rise0_r;
465 prev_rd_fall0_r <= #TCQ
sel_rd_fall0_r;
466 prev_rd_rise1_r <= #TCQ
sel_rd_rise1_r;
467 prev_rd_fall1_r <= #TCQ
sel_rd_fall1_r;
468 prev_rd_rise2_r <= #TCQ
sel_rd_rise2_r;
469 prev_rd_fall2_r <= #TCQ
sel_rd_fall2_r;
470 prev_rd_rise3_r <= #TCQ
sel_rd_rise3_r;
471 prev_rd_fall3_r <= #TCQ
sel_rd_fall3_r;
475 // Each bit of each byte is compared with previous data to
480 if (
nCK_PER_CLK ==
4)
begin:
gen_pat_match_div4
482 always @(
posedge clk)
begin
483 if (
rd_active_r)
begin
484 rise_win <= #TCQ ((|
sel_rd_rise0_r) | (|
sel_rd_rise1_r) | (|
sel_rd_rise2_r) | (|
sel_rd_rise3_r));
485 fall_win <= #TCQ ((&
sel_rd_rise0_r) & (&
sel_rd_rise1_r) & (&
sel_rd_rise2_r) & (&
sel_rd_rise3_r));
489 for (
pt_j =
0;
pt_j <
DRAM_WIDTH;
pt_j =
pt_j +
1)
begin:
gen_pat_match
491 always @(
posedge clk)
begin
492 if (
sel_rd_rise0_r[
pt_j] ==
prev_rd_rise0_r[
pt_j])
493 pat_match_rise0_r[
pt_j] <= #TCQ
1'b1;
495 pat_match_rise0_r[
pt_j] <= #TCQ
1'b0;
497 if (
sel_rd_fall0_r[
pt_j] ==
prev_rd_fall0_r[
pt_j])
498 pat_match_fall0_r[
pt_j] <= #TCQ
1'b1;
500 pat_match_fall0_r[
pt_j] <= #TCQ
1'b0;
502 if (
sel_rd_rise1_r[
pt_j] ==
prev_rd_rise1_r[
pt_j])
503 pat_match_rise1_r[
pt_j] <= #TCQ
1'b1;
505 pat_match_rise1_r[
pt_j] <= #TCQ
1'b0;
507 if (
sel_rd_fall1_r[
pt_j] ==
prev_rd_fall1_r[
pt_j])
508 pat_match_fall1_r[
pt_j] <= #TCQ
1'b1;
510 pat_match_fall1_r[
pt_j] <= #TCQ
1'b0;
512 if (
sel_rd_rise2_r[
pt_j] ==
prev_rd_rise2_r[
pt_j])
513 pat_match_rise2_r[
pt_j] <= #TCQ
1'b1;
515 pat_match_rise2_r[
pt_j] <= #TCQ
1'b0;
517 if (
sel_rd_fall2_r[
pt_j] ==
prev_rd_fall2_r[
pt_j])
518 pat_match_fall2_r[
pt_j] <= #TCQ
1'b1;
520 pat_match_fall2_r[
pt_j] <= #TCQ
1'b0;
522 if (
sel_rd_rise3_r[
pt_j] ==
prev_rd_rise3_r[
pt_j])
523 pat_match_rise3_r[
pt_j] <= #TCQ
1'b1;
525 pat_match_rise3_r[
pt_j] <= #TCQ
1'b0;
527 if (
sel_rd_fall3_r[
pt_j] ==
prev_rd_fall3_r[
pt_j])
528 pat_match_fall3_r[
pt_j] <= #TCQ
1'b1;
530 pat_match_fall3_r[
pt_j] <= #TCQ
1'b0;
534 always @(
posedge clk)
begin
535 pat_match_rise0_and_r <= #TCQ &
pat_match_rise0_r;
536 pat_match_fall0_and_r <= #TCQ &
pat_match_fall0_r;
537 pat_match_rise1_and_r <= #TCQ &
pat_match_rise1_r;
538 pat_match_fall1_and_r <= #TCQ &
pat_match_fall1_r;
539 pat_match_rise2_and_r <= #TCQ &
pat_match_rise2_r;
540 pat_match_fall2_and_r <= #TCQ &
pat_match_fall2_r;
541 pat_match_rise3_and_r <= #TCQ &
pat_match_rise3_r;
542 pat_match_fall3_and_r <= #TCQ &
pat_match_fall3_r;
543 pat_data_match_r <= #TCQ (
//pat_match_rise0_and_r &&
544 //pat_match_fall0_and_r &&
545 pat_match_rise1_and_r &&
546 pat_match_fall1_and_r &&
547 pat_match_rise2_and_r &&
548 pat_match_fall2_and_r &&
549 pat_match_rise3_and_r &&
550 pat_match_fall3_and_r);
551 pat_data_match_valid_r <= #TCQ
rd_active_r2;
554 always @(
posedge clk)
555 pat_data_match_valid_r1 <= #TCQ
pat_data_match_valid_r;
557 end else if (
nCK_PER_CLK ==
2)
begin:
gen_pat_match_div2
559 always @(
posedge clk)
begin
560 if (
rd_active_r)
begin
561 rise_win <= #TCQ ((|
sel_rd_rise0_r) | (|
sel_rd_rise1_r));
562 fall_win <= #TCQ ((&
sel_rd_rise0_r) & (&
sel_rd_rise1_r));
566 for (
pt_j =
0;
pt_j <
DRAM_WIDTH;
pt_j =
pt_j +
1)
begin:
gen_pat_match
568 always @(
posedge clk)
begin
569 if (
sel_rd_rise0_r[
pt_j] ==
prev_rd_rise0_r[
pt_j])
570 pat_match_rise0_r[
pt_j] <= #TCQ
1'b1;
572 pat_match_rise0_r[
pt_j] <= #TCQ
1'b0;
574 if (
sel_rd_fall0_r[
pt_j] ==
prev_rd_fall0_r[
pt_j])
575 pat_match_fall0_r[
pt_j] <= #TCQ
1'b1;
577 pat_match_fall0_r[
pt_j] <= #TCQ
1'b0;
579 if (
sel_rd_rise1_r[
pt_j] ==
prev_rd_rise1_r[
pt_j])
580 pat_match_rise1_r[
pt_j] <= #TCQ
1'b1;
582 pat_match_rise1_r[
pt_j] <= #TCQ
1'b0;
584 if (
sel_rd_fall1_r[
pt_j] ==
prev_rd_fall1_r[
pt_j])
585 pat_match_fall1_r[
pt_j] <= #TCQ
1'b1;
587 pat_match_fall1_r[
pt_j] <= #TCQ
1'b0;
592 always @(
posedge clk)
begin
593 pat_match_rise0_and_r <= #TCQ &
pat_match_rise0_r;
594 pat_match_fall0_and_r <= #TCQ &
pat_match_fall0_r;
595 pat_match_rise1_and_r <= #TCQ &
pat_match_rise1_r;
596 pat_match_fall1_and_r <= #TCQ &
pat_match_fall1_r;
597 pat_data_match_r <= #TCQ (
//pat_match_rise0_and_r &&
598 //pat_match_fall0_and_r &&
599 pat_match_rise1_and_r &&
600 pat_match_fall1_and_r);
601 pat_data_match_valid_r <= #TCQ
rd_active_r2;
604 always @(
posedge clk)
605 pat_data_match_valid_r1 <= #TCQ
pat_data_match_valid_r;
610 // Stable count of 16 PO Stage3 taps at 2x the resolution of stage2 taps
611 // Required to inhibit false edge detection due to clock jitter
612 always @(
posedge clk)
begin
613 if (
rst | (
pat_data_match_valid_r & ~
pat_data_match_r &
614 (
ocal_state_r ==
OCAL_NEW_DQS_WAIT)) |
615 (
ocal_state_r ==
OCAL_STG3_CALC))
616 stable_rise_stg3_cnt <= #TCQ
'd0;
617 else if ((!
stg3_tap_cnt_eq_oclkdelay_init_val) &
618 pat_data_match_valid_r &
pat_data_match_r &
619 (
ocal_state_r ==
OCAL_NEW_DQS_WAIT) &
620 (
stable_rise_stg3_cnt <
'd8) & ~
rise_win)
621 stable_rise_stg3_cnt <= #TCQ
stable_rise_stg3_cnt +
1;
624 always @(
posedge clk)
begin
625 if (
rst | (
stable_rise_stg3_cnt !=
'd8))
626 stable_rise_eye_r <= #TCQ
1'b0;
627 else if (
stable_rise_stg3_cnt ==
'd8)
628 stable_rise_eye_r <= #TCQ
1'b1;
631 always @(
posedge clk)
begin
632 if (
rst | (
pat_data_match_valid_r & ~
pat_data_match_r &
633 (
ocal_state_r ==
OCAL_NEW_DQS_WAIT)) |
634 (
ocal_state_r ==
OCAL_STG3_CALC))
635 stable_fall_stg3_cnt <= #TCQ
'd0;
636 else if ((!
stg3_tap_cnt_eq_oclkdelay_init_val) &
637 pat_data_match_valid_r &
pat_data_match_r &
638 (
ocal_state_r ==
OCAL_NEW_DQS_WAIT) &
639 (
stable_fall_stg3_cnt <
'd8) &
fall_win)
640 stable_fall_stg3_cnt <= #TCQ
stable_fall_stg3_cnt +
1;
643 always @(
posedge clk)
begin
644 if (
rst | (
stable_fall_stg3_cnt !=
'd8))
645 stable_fall_eye_r <= #TCQ
1'b0;
646 else if (
stable_fall_stg3_cnt ==
'd8)
647 stable_fall_eye_r <= #TCQ
1'b1;
650 always @(
posedge clk)
651 if ((
ocal_state_r ==
OCAL_STG3_SEL_WAIT) ||
652 (
ocal_state_r ==
OCAL_STG3_EN_WAIT) ||
653 (
ocal_state_r ==
OCAL_STG3_WAIT) ||
654 (
ocal_state_r ==
OCAL_STG3_INC_WAIT) ||
655 (
ocal_state_r ==
OCAL_STG3_DEC_WAIT) ||
656 (
ocal_state_r ==
OCAL_STG2_WAIT) ||
657 (
ocal_state_r ==
OCAL_STG2_DEC_WAIT) ||
658 (
ocal_state_r ==
OCAL_INC_DONE_WAIT) ||
659 (
ocal_state_r ==
OCAL_DEC_DONE_WAIT))
660 wait_cnt_en_r <= #TCQ
1'b1;
662 wait_cnt_en_r <= #TCQ
1'b0;
664 always @(
posedge clk)
665 if (!
wait_cnt_en_r)
begin
666 wait_cnt_r <= #TCQ
'b0;
667 cnt_next_state <= #TCQ
1'b0;
669 if (
wait_cnt_r !=
WAIT_CNT -
1)
begin
670 wait_cnt_r <= #TCQ
wait_cnt_r +
1;
671 cnt_next_state <= #TCQ
1'b0;
673 // Need to reset to 0 to handle the case when there are two
674 // different WAIT states back-to-back
675 wait_cnt_r <= #TCQ
'b0;
676 cnt_next_state <= #TCQ
1'b1;
680 always @(
posedge clk)
begin
682 for (
i=
0;
i <
DQS_WIDTH;
i =
i +
1)
begin:
rst_ocal_tap_cnt
683 ocal_tap_cnt_r[
i] <= #TCQ
'b0;
685 end else if (
stg3_dec_r && ~
stg3_dec)
686 ocal_tap_cnt_r[
cnt_dqs_r][
5:
0] <= #TCQ stg3_tap_cnt;
689 always @(
posedge clk)
begin
690 if (rst || (ocal_state_r == OCAL_NEW_DQS_READ) ||
691 (ocal_state_r == OCAL_STG3_CALC) ||
692 (ocal_state_r == OCAL_DONE))
693 prech_done_r <= #TCQ
1'b0;
695 prech_done_r <= #TCQ
1'b1;
701 // setting stg3_tap_cnt == oclkdelay_int_val
703 always @(
posedge clk)
begin
704 if (
rst || (
ocal_state_r ==
OCAL_NEXT_DQS))
begin
705 stg3_tap_cnt_eq_oclkdelay_init_val <= #TCQ
1'b1;
707 if (
ocal_state_r ==
OCAL_DONE)
708 stg3_tap_cnt_eq_oclkdelay_init_val <= #TCQ
1'b0;
709 else if (
ocal_state_r ==
OCAL_STG3_DEC)
710 stg3_tap_cnt_eq_oclkdelay_init_val <= #TCQ (
stg3_tap_cnt ==
oclkdelay_init_val+
1);
711 else if (
ocal_state_r ==
OCAL_STG3_INC)
712 stg3_tap_cnt_eq_oclkdelay_init_val <= #TCQ (
stg3_tap_cnt ==
oclkdelay_init_val-
1);
713 end // else: !if((rst || (ocal_state_r == OCAL_IDLE)) begin...
714 end // always @ (posedge clk)
716 // setting sg3_tap_cng > 20
717 // always @(posedge clk) begin
718 // if ((rst)|| (ocal_state_r == OCAL_NEXT_DQS)) begin
719 // stg3_tap_cnt_gt_20 <= #TCQ 1'b0;
720 // end else begin // if (rst)
721 // if (ocal_state_r == OCAL_STG3_DEC)
722 // stg3_tap_cnt_gt_20 <= #TCQ (stg3_tap_cnt >= 'd22);
723 // else if (ocal_state_r == OCAL_STG3_INC)
724 // stg3_tap_cnt_gt_20 <= #TCQ (stg3_tap_cnt >= 'd20);
725 // end // else: !if((rst || (ocal_state_r == OCAL_IDLE)) begin...
726 // end // always @ (posedge clk)
728 // setting sg3_tap_cnt == 0
729 always @(
posedge clk)
begin
730 if ((
rst)|| (
ocal_state_r ==
OCAL_NEXT_DQS) || (
ocal_state_r ==
OCAL_STG3_INC) )
begin
731 stg3_tap_cnt_eq_0 <= #TCQ
1'b0;
732 end else begin // if (rst)
733 if (
ocal_state_r ==
OCAL_STG3_DEC)
734 stg3_tap_cnt_eq_0 <= #TCQ (
stg3_tap_cnt ==
'd1);
735 end // else: !if((rst || (ocal_state_r == OCAL_IDLE)) begin...
736 end // always @ (posedge clk)
738 // setting sg3_tap_cnt == 63
739 always @(
posedge clk)
begin
740 if ((
rst)|| (
ocal_state_r ==
OCAL_NEXT_DQS))
begin
741 stg3_tap_cnt_eq_63 <= #TCQ
1'b0;
742 end else begin // if (rst)
743 if (
ocal_state_r ==
OCAL_STG3_INC)
744 stg3_tap_cnt_eq_63 <= #TCQ (
stg3_tap_cnt >=
'd62);
745 else if (
ocal_state_r ==
OCAL_STG3_DEC)
746 stg3_tap_cnt_eq_63 <= #TCQ
1'b0;
747 end // else: !if((rst || (ocal_state_r == OCAL_IDLE)) begin...
748 end // always @ (posedge clk)
750 // setting sg3_tap_cnt < ocaldelay_init_val
751 always @(
posedge clk)
begin
752 if ((
rst)|| (
ocal_state_r ==
OCAL_NEXT_DQS))
begin
753 stg3_tap_cnt_less_oclkdelay_init_val <= #TCQ
1'b0;
754 end else begin // if (rst)
755 if (
ocal_state_r ==
OCAL_STG3_DEC)
756 stg3_tap_cnt_less_oclkdelay_init_val <= #TCQ (
stg3_tap_cnt <=
oclkdelay_init_val);
757 else if (
ocal_state_r ==
OCAL_STG3_INC)
758 stg3_tap_cnt_less_oclkdelay_init_val <= #TCQ (
stg3_tap_cnt <=
oclkdelay_init_val-
2);
759 end // else: !if((rst || (ocal_state_r == OCAL_IDLE)) begin...
760 end // always @ (posedge clk)
762 // setting stg3_incdec_limit == 15
763 always @(
posedge clk)
begin
764 if (
rst || (
ocal_state_r ==
OCAL_NEXT_DQS) || (
ocal_state_r ==
OCAL_DONE))
begin
765 stg3_limit <= #TCQ
1'b0;
766 end else if ((
ocal_state_r ==
OCAL_STG3_WAIT) || (
ocal_state_r ==
OCAL_STG2_WAIT))
begin
767 stg3_limit <= #TCQ (
stg3_incdec_limit ==
'd14);
771 // Registers feeding into the ocal_final_cnt_r computation
772 // Equation is in the form of ((A-B)/2) + C + D where the values taken are
773 // A = ocal_fall_edge_taps, ocal_rise_right_edge, stg3_tap_cnt or ocal_fall_edge2_taps
774 // B = ocal_fall_edge1_taps, ocal_rise_edge1_taps or '0'
775 // C = (stg3_tap_cnt - ocal_rise_right_edge), '0' or '1'
777 always @(
posedge clk)
begin
778 if (
rst || (
ocal_state_r ==
OCAL_NEXT_DQS) || (
ocal_state_r ==
OCAL_DONE))
779 ocal_final_cnt_r_mux_a <= #TCQ
'd0;
780 else if (|
ocal_rise_right_edge)
begin
781 if (
ocal_fall_edge2_found &&
ocal_fall_edge1_found)
782 ocal_final_cnt_r_mux_a <= #TCQ
ocal_fall_edge2_taps;
784 ocal_final_cnt_r_mux_a <= #TCQ
ocal_rise_right_edge;
785 end else if (
ocal_rise_edge2_found)
786 ocal_final_cnt_r_mux_a <= #TCQ
ocal_rise_edge2_taps;
787 else if (~
ocal_rise_edge2_found &&
ocal_rise_edge1_found)
788 ocal_final_cnt_r_mux_a <= #TCQ
stg3_tap_cnt;
789 else if (
ocal_fall_edge2_found &&
ocal_fall_edge1_found)
790 ocal_final_cnt_r_mux_a <= #TCQ
ocal_fall_edge2_taps;
793 always @(
posedge clk)
begin
794 if (
rst || (
ocal_state_r ==
OCAL_NEXT_DQS) || (
ocal_state_r ==
OCAL_DONE))
795 ocal_final_cnt_r_mux_b <= #TCQ
'd0;
796 else if (|
ocal_rise_right_edge)
begin
797 if (
ocal_fall_edge2_found &&
ocal_fall_edge1_found)
798 ocal_final_cnt_r_mux_b <= #TCQ
ocal_fall_edge1_taps;
800 ocal_final_cnt_r_mux_b <= #TCQ
ocal_rise_edge1_taps;
801 end else if (
ocal_rise_edge2_found &&
ocal_rise_edge1_found)
802 ocal_final_cnt_r_mux_b <= #TCQ
ocal_rise_edge1_taps;
803 else if (
ocal_rise_edge2_found && ~
ocal_rise_edge1_found)
804 ocal_final_cnt_r_mux_b <= #TCQ
'd0;
805 else if (~
ocal_rise_edge2_found &&
ocal_rise_edge1_found)
806 ocal_final_cnt_r_mux_b <= #TCQ
ocal_rise_edge1_taps;
807 else if (
ocal_fall_edge2_found &&
ocal_fall_edge1_found)
808 ocal_final_cnt_r_mux_b <= #TCQ
ocal_fall_edge1_taps;
811 always @(
posedge clk)
begin
812 if (
rst || (
ocal_state_r ==
OCAL_NEXT_DQS) || (
ocal_state_r ==
OCAL_DONE))
813 ocal_final_cnt_r_mux_c <= #TCQ
'd0;
814 else if (|
ocal_rise_right_edge)
begin
815 if (
ocal_fall_edge2_found &&
ocal_fall_edge1_found)
816 ocal_final_cnt_r_mux_c <= #TCQ
'd1;
818 ocal_final_cnt_r_mux_c <= #TCQ (
stg3_tap_cnt -
ocal_rise_right_edge);
819 end else if (~
ocal_rise_edge2_found &&
ocal_rise_edge1_found)
820 ocal_final_cnt_r_mux_c <= #TCQ
'd0;
822 ocal_final_cnt_r_mux_c <= #TCQ
'd1;
825 always @(
posedge clk)
begin
826 if (
rst || (
ocal_state_r ==
OCAL_NEXT_DQS) || (
ocal_state_r ==
OCAL_DONE))
827 ocal_final_cnt_r_mux_d <= #TCQ
'd0;
828 else if (((|
ocal_rise_right_edge) &&
829 (
ocal_fall_edge2_found &&
ocal_fall_edge1_found)) ||
830 (
ocal_fall_edge2_found &&
ocal_fall_edge1_found))
831 ocal_final_cnt_r_mux_d <= #TCQ
'd32;
833 ocal_final_cnt_r_mux_d <= #TCQ
'd0;
836 always @(
posedge clk)
begin
837 if (
rst || (
ocal_state_r ==
OCAL_NEXT_DQS) || (
ocal_state_r ==
OCAL_DONE))
838 ocal_final_cnt_r <= #TCQ
'd0;
839 else if (
ocal_state_r ==
OCAL_STG3_CALC)
840 ocal_final_cnt_r <= #TCQ ((
ocal_final_cnt_r_mux_a -
ocal_final_cnt_r_mux_b)>>
1) +
841 ocal_final_cnt_r_mux_c +
ocal_final_cnt_r_mux_d;
846 for (
dqs_q=
0;
dqs_q <
DQS_WIDTH;
dqs_q =
dqs_q +
1)
begin:
tap_cnt_split
847 assign wl_po_fine_cnt_w[
dqs_q] =
wl_po_fine_cnt[
6*
dqs_q+:
6];
852 always @(
posedge clk)
begin
854 ocal_state_r <= #TCQ
OCAL_IDLE;
855 cnt_dqs_r <= #TCQ
'd0;
856 stg3_tap_cnt <= #TCQ
oclkdelay_init_val;
857 stg3_incdec_limit <= #TCQ
'd0;
858 stg3_dec2inc <= #TCQ
1'b0;
859 stg2_tap_cnt <= #TCQ
'd0;
860 stg2_inc2_cnt <= #TCQ
2'b00;
861 stg2_dec2_cnt <= #TCQ
2'b00;
862 stg2_dec_cnt <= #TCQ
'd0;
863 stg3_dec <= #TCQ
1'b0;
864 wrlvl_final <= #TCQ
1'b0;
865 oclk_calib_resume <= #TCQ
1'b0;
866 oclk_prech_req <= #TCQ
1'b0;
867 ocal_inc_cnt <= #TCQ
'd0;
868 ocal_dec_cnt <= #TCQ
'd0;
869 ocal_stg3_inc_en <= #TCQ
1'b0;
870 ocal_rise_edge1_found <= #TCQ
1'b0;
871 ocal_rise_edge2_found <= #TCQ
1'b0;
872 ocal_rise_edge1_found_timing <= #TCQ
1'b0;
873 ocal_rise_edge2_found_timing <= #TCQ
1'b0;
874 ocal_rise_right_edge <= #TCQ
'd0;
875 ocal_rise_edge1_taps <= #TCQ
'd0;
876 ocal_rise_edge2_taps <= #TCQ
'd0;
877 ocal_fall_edge1_found <= #TCQ
1'b0;
878 ocal_fall_edge2_found <= #TCQ
1'b0;
879 ocal_fall_edge1_taps <= #TCQ
'd0;
880 ocal_fall_edge2_taps <= #TCQ
'd0;
881 ocal_byte_done <= #TCQ
1'b0;
882 ocal_wrlvl_done <= #TCQ
1'b0;
883 ocal_done_r <= #TCQ
1'b0;
884 po_stg23_sel <= #TCQ
1'b0;
885 po_en_stg23 <= #TCQ
1'b0;
886 po_stg23_incdec <= #TCQ
1'b0;
887 ocal_final_cnt_r_calc <= #TCQ
1'b0;
892 if (
oclkdelay_calib_start && ~
oclkdelay_calib_start_r)
begin
893 ocal_state_r <= #TCQ
OCAL_NEW_DQS_WAIT;
894 stg3_tap_cnt <= #TCQ
oclkdelay_init_val;
895 stg2_tap_cnt <= #TCQ
wl_po_fine_cnt_w[
cnt_dqs_r];
899 OCAL_NEW_DQS_READ:
begin
900 oclk_prech_req <= #TCQ
1'b0;
901 oclk_calib_resume <= #TCQ
1'b0;
902 if (
pat_data_match_valid_r)
903 ocal_state_r <= #TCQ
OCAL_NEW_DQS_WAIT;
906 OCAL_NEW_DQS_WAIT:
begin
907 oclk_calib_resume <= #TCQ
1'b0;
908 oclk_prech_req <= #TCQ
1'b0;
909 po_en_stg23 <= #TCQ
1'b0;
910 po_stg23_incdec <= #TCQ
1'b0;
911 if (
pat_data_match_valid_r && !
stg3_tap_cnt_eq_oclkdelay_init_val)
begin
912 if ((
stg3_limit && ~
ocal_stg3_inc_en) ||
913 stg3_tap_cnt ==
'd0)
begin
914 // No write levling performed to avoid stage 2 coarse dec.
915 // Therefore stage 3 taps can only be decremented by an
916 // additional 15 taps after stage 2 taps reach 63.
917 ocal_state_r <= #TCQ
OCAL_STG3_SEL;
918 ocal_stg3_inc_en <= #TCQ
1'b1;
919 stg3_incdec_limit <= #TCQ
'd0;
920 // An edge was detected
921 end else if (~
pat_data_match_r)
begin
922 // Sticky bit - asserted after we encounter an edge, although
923 // the current edge may not be considered the "first edge" this
924 // just means we found at least one edge
925 if (~
ocal_stg3_inc_en)
begin
926 if (|
stable_fall_stg3_cnt && ~
ocal_fall_edge1_found)
begin
927 ocal_fall_edge1_found <= #TCQ
1'b1;
928 ocal_fall_edge1_taps <= #TCQ
stg3_tap_cnt +
1;
930 ocal_rise_edge1_found <= #TCQ
1'b1;
931 ocal_rise_edge1_found_timing <= #TCQ
1'b1;
934 // Sarting point was in the jitter region close to the right edge
935 if (~
stable_rise_eye_r && ~
ocal_stg3_inc_en)
begin
936 ocal_rise_right_edge <= #TCQ
stg3_tap_cnt;
937 ocal_state_r <= #TCQ
OCAL_STG3_SEL;
938 // Starting point was in the valid window close to the right edge
939 // Or away from the right edge hence no stable_eye_r condition
940 // Or starting point was in the right jitter region and ocal_rise_right_edge
942 end else if (
ocal_stg3_inc_en)
begin
944 if (
stable_fall_eye_r)
begin
945 ocal_state_r <= #TCQ
OCAL_STG3_CALC;
946 ocal_fall_edge2_found <= #TCQ
1'b1;
947 ocal_fall_edge2_taps <= #TCQ
stg3_tap_cnt -
1;
949 ocal_state_r <= #TCQ
OCAL_STG3_CALC;
950 ocal_rise_edge2_found <= #TCQ
1'b1;
951 ocal_rise_edge2_found_timing <= #TCQ
1'b1;
952 ocal_rise_edge2_taps <= #TCQ
stg3_tap_cnt -
1;
954 // Starting point in the valid window away from left edge
955 // Assuming starting point will not be in valid window close to
957 end else if (
stable_rise_eye_r)
begin
958 ocal_rise_edge1_taps <= #TCQ
stg3_tap_cnt +
1;
959 ocal_state_r <= #TCQ
OCAL_STG3_SEL;
960 ocal_stg3_inc_en <= #TCQ
1'b1;
961 stg3_incdec_limit <= #TCQ
'd0;
963 ocal_state_r <= #TCQ
OCAL_STG3_SEL;
965 ocal_state_r <= #TCQ
OCAL_STG3_SEL;
966 end else if (
stg3_tap_cnt_eq_oclkdelay_init_val)
967 ocal_state_r <= #TCQ
OCAL_STG3_SEL;
968 else if ((
stg3_limit &&
ocal_stg3_inc_en) ||
969 (
stg3_tap_cnt_eq_63))
begin
970 ocal_state_r <= #TCQ
OCAL_STG3_CALC;
971 stg3_incdec_limit <= #TCQ
'd0;
976 po_stg23_sel <= #TCQ
1'b1;
977 ocal_wrlvl_done <= #TCQ
1'b0;
978 ocal_state_r <= #TCQ
OCAL_STG3_SEL_WAIT;
979 ocal_final_cnt_r_calc <= #TCQ
1'b0;
982 OCAL_STG3_SEL_WAIT:
begin
983 if (
cnt_next_state)
begin
984 ocal_state_r <= #TCQ
OCAL_STG3_EN_WAIT;
985 if (
ocal_stg3_inc_en)
begin
986 po_stg23_incdec <= #TCQ
1'b1;
987 if (
stg3_tap_cnt_less_oclkdelay_init_val)
begin
988 ocal_inc_cnt <= #TCQ
oclkdelay_init_val -
stg3_tap_cnt;
989 stg3_dec2inc <= #TCQ
1'b1;
990 oclk_prech_req <= #TCQ
1'b1;
993 po_stg23_incdec <= #TCQ
1'b0;
995 ocal_dec_cnt <= #TCQ
ocal_final_cnt_r;
1000 OCAL_STG3_EN_WAIT:
begin
1001 if (
cnt_next_state)
begin
1002 if (
ocal_stg3_inc_en)
1003 ocal_state_r <= #TCQ
OCAL_STG3_INC;
1005 ocal_state_r <= #TCQ
OCAL_STG3_DEC;
1009 OCAL_STG3_DEC:
begin
1010 po_en_stg23 <= #TCQ
1'b1;
1011 stg3_tap_cnt <= #TCQ
stg3_tap_cnt -
1;
1012 if (
ocal_dec_cnt ==
1)
begin
1013 ocal_byte_done <= #TCQ
1'b1;
1014 ocal_state_r <= #TCQ
OCAL_DEC_DONE_WAIT;
1015 ocal_dec_cnt <= #TCQ
ocal_dec_cnt -
1;
1016 end else if (
ocal_dec_cnt >
'd0)
begin
1017 ocal_state_r <= #TCQ
OCAL_STG3_DEC_WAIT;
1018 ocal_dec_cnt <= #TCQ
ocal_dec_cnt -
1;
1020 ocal_state_r <= #TCQ
OCAL_STG3_WAIT;
1023 OCAL_STG3_DEC_WAIT:
begin
1024 po_en_stg23 <= #TCQ
1'b0;
1025 if (
cnt_next_state)
begin
1026 if (
ocal_dec_cnt >
'd0)
1027 ocal_state_r <= #TCQ
OCAL_STG3_DEC;
1029 ocal_state_r <= #TCQ
OCAL_DEC_DONE_WAIT;
1033 OCAL_DEC_DONE_WAIT:
begin
1034 // Required to make sure that po_stg23_incdec
1035 // de-asserts some time after de-assertion of
1037 po_en_stg23 <= #TCQ
1'b0;
1038 if (
cnt_next_state)
begin
1039 // Final stage 3 decrement completed, proceed
1040 // to stage 2 tap decrement
1041 ocal_state_r <= #TCQ
OCAL_STG2_SEL;
1042 po_stg23_incdec <= #TCQ
1'b0;
1043 stg3_dec <= #TCQ
1'b0;
1047 OCAL_STG3_WAIT:
begin
1048 po_en_stg23 <= #TCQ
1'b0;
1049 if (
cnt_next_state)
begin
1050 po_stg23_incdec <= #TCQ
1'b0;
1051 if ((
stg2_tap_cnt !=
6'd63) || (
stg2_tap_cnt !=
6'd0))
1052 ocal_state_r <= #TCQ
OCAL_STG2_SEL;
1054 oclk_calib_resume <= #TCQ
1'b1;
1055 ocal_state_r <= #TCQ
OCAL_NEW_DQS_WAIT;
1056 stg3_incdec_limit <= #TCQ
stg3_incdec_limit +
1;
1061 OCAL_STG2_SEL:
begin
1062 po_stg23_sel <= #TCQ
1'b0;
1063 po_en_stg23 <= #TCQ
1'b0;
1064 po_stg23_incdec <= #TCQ
1'b0;
1065 ocal_state_r <= #TCQ
OCAL_STG2_WAIT;
1066 stg2_inc2_cnt <= #TCQ
2'b01;
1067 stg2_dec2_cnt <= #TCQ
2'b01;
1070 OCAL_STG2_WAIT:
begin
1071 po_en_stg23 <= #TCQ
1'b0;
1072 po_stg23_incdec <= #TCQ
1'b0;
1073 if (
cnt_next_state)
begin
1074 if (
ocal_byte_done)
begin
1075 if (
stg2_tap_cnt >
'd0)
begin
1076 // Decrement stage 2 taps to '0' before
1077 // final write level is performed
1078 ocal_state_r <= #TCQ
OCAL_STG2_DEC;
1079 stg2_dec_cnt <= #TCQ
stg2_tap_cnt;
1081 ocal_state_r <= #TCQ
OCAL_NEXT_DQS;
1082 ocal_byte_done <= #TCQ
1'b0;
1084 end else if (
stg3_dec2inc && (
stg2_tap_cnt >
'd0))
begin
1085 // Decrement stage 2 tap to initial value before
1086 // edge 2 detection begins
1087 ocal_state_r <= #TCQ
OCAL_STG2_DEC;
1088 stg2_dec_cnt <= #TCQ
stg2_tap_cnt -
wl_po_fine_cnt_w[
cnt_dqs_r];
1089 end else if (~
ocal_stg3_inc_en && (
stg2_tap_cnt <
6'd63))
begin
1090 // Increment stage 2 taps by 2 for every stage 3 tap decrement
1091 // as part of edge 1 detection to avoid tDQSS violation between
1093 ocal_state_r <= #TCQ
OCAL_STG2_INC;
1094 end else if (
ocal_stg3_inc_en && (
stg2_tap_cnt >
6'd0))
begin
1095 // Decrement stage 2 taps by 2 for every stage 3 tap increment
1096 // as part of edge 2 detection to avoid tDQSS violation between
1098 ocal_state_r <= #TCQ
OCAL_STG2_DEC;
1100 oclk_calib_resume <= #TCQ
1'b1;
1101 ocal_state_r <= #TCQ
OCAL_NEW_DQS_WAIT;
1102 stg3_incdec_limit <= #TCQ
stg3_incdec_limit +
1;
1107 OCAL_STG2_INC:
begin
1108 po_en_stg23 <= #TCQ
1'b1;
1109 po_stg23_incdec <= #TCQ
1'b1;
1110 stg2_tap_cnt <= #TCQ
stg2_tap_cnt +
1;
1111 if (
stg2_inc2_cnt >
2'b00)
begin
1112 stg2_inc2_cnt <=
stg2_inc2_cnt -
1;
1113 ocal_state_r <= #TCQ
OCAL_STG2_WAIT;
1114 end else if (
stg2_tap_cnt ==
6'd62)
begin
1115 ocal_state_r <= #TCQ
OCAL_STG2_WAIT;
1117 oclk_calib_resume <= #TCQ
1'b1;
1118 ocal_state_r <= #TCQ
OCAL_NEW_DQS_WAIT;
1122 OCAL_STG2_DEC:
begin
1123 po_en_stg23 <= #TCQ
1'b1;
1124 po_stg23_incdec <= #TCQ
1'b0;
1125 stg2_tap_cnt <= #TCQ
stg2_tap_cnt -
1;
1126 if (
stg2_dec_cnt >
6'd0)
begin
1127 stg2_dec_cnt <= #TCQ
stg2_dec_cnt -
1;
1128 ocal_state_r <= #TCQ
OCAL_STG2_DEC_WAIT;
1129 end else if (
stg2_dec2_cnt >
2'b00)
begin
1130 stg2_dec2_cnt <=
stg2_dec2_cnt -
1;
1131 ocal_state_r <= #TCQ
OCAL_STG2_WAIT;
1132 end else if (
stg2_tap_cnt ==
6'd1)
1133 ocal_state_r <= #TCQ
OCAL_STG2_WAIT;
1135 oclk_calib_resume <= #TCQ
1'b1;
1136 ocal_state_r <= #TCQ
OCAL_NEW_DQS_WAIT;
1140 OCAL_STG2_DEC_WAIT:
begin
1141 po_en_stg23 <= #TCQ
1'b0;
1142 po_stg23_incdec <= #TCQ
1'b0;
1143 if (
cnt_next_state)
begin
1144 if (
stg2_dec_cnt >
6'd0)
begin
1145 ocal_state_r <= #TCQ
OCAL_STG2_DEC;
1146 end else if (
ocal_byte_done)
begin
1147 ocal_state_r <= #TCQ
OCAL_NEXT_DQS;
1148 ocal_byte_done <= #TCQ
1'b0;
1149 end else if (
prech_done_r &&
stg3_dec2inc)
begin
1150 stg3_dec2inc <= #TCQ
1'b0;
1151 if (
stg3_tap_cnt_eq_63)
1152 ocal_state_r <= #TCQ
OCAL_STG3_CALC;
1154 ocal_state_r <= #TCQ
OCAL_NEW_DQS_READ;
1155 oclk_calib_resume <= #TCQ
1'b1;
1161 OCAL_STG3_CALC:
begin
1162 if (
ocal_final_cnt_r_calc)
begin
1163 ocal_state_r <= #TCQ
OCAL_STG3_SEL;
1164 stg3_dec <= #TCQ
1'b1;
1165 ocal_stg3_inc_en <= #TCQ
1'b0;
1167 ocal_final_cnt_r_calc <= #TCQ
1'b1;
1170 OCAL_STG3_INC:
begin
1171 po_en_stg23 <= #TCQ
1'b1;
1172 stg3_tap_cnt <= #TCQ
stg3_tap_cnt +
1;
1173 if (
ocal_inc_cnt >
'd0)
1174 ocal_inc_cnt <= #TCQ
ocal_inc_cnt -
1;
1175 if (
ocal_inc_cnt ==
1)
1176 ocal_state_r <= #TCQ
OCAL_INC_DONE_WAIT;
1178 ocal_state_r <= #TCQ
OCAL_STG3_INC_WAIT;
1181 OCAL_STG3_INC_WAIT:
begin
1182 po_en_stg23 <= #TCQ
1'b0;
1183 po_stg23_incdec <= #TCQ
1'b1;
1184 if (
cnt_next_state)
begin
1185 if (
ocal_inc_cnt >
'd0)
1186 ocal_state_r <= #TCQ
OCAL_STG3_INC;
1188 ocal_state_r <= #TCQ
OCAL_STG2_SEL;
1189 po_stg23_incdec <= #TCQ
1'b0;
1194 OCAL_INC_DONE_WAIT:
begin
1195 // Required to make sure that po_stg23_incdec
1196 // de-asserts some time after de-assertion of
1198 po_en_stg23 <= #TCQ
1'b0;
1199 oclk_prech_req <= #TCQ
1'b0;
1200 if (
cnt_next_state)
begin
1201 ocal_state_r <= #TCQ
OCAL_STG2_SEL;
1203 po_stg23_incdec <= #TCQ
1'b0;
1207 OCAL_NEXT_DQS:
begin
1208 ocal_final_cnt_r_calc <= #TCQ
1'b0;
1209 po_en_stg23 <= #TCQ
1'b0;
1210 po_stg23_incdec <= #TCQ
1'b0;
1211 stg3_tap_cnt <= #TCQ
6'd0;
1212 ocal_rise_edge1_found <= #TCQ
1'b0;
1213 ocal_rise_edge2_found <= #TCQ
1'b0;
1214 ocal_rise_edge1_found_timing <= #TCQ
1'b0;
1215 ocal_rise_edge2_found_timing <= #TCQ
1'b0;
1216 ocal_rise_edge1_taps <= #TCQ
'd0;
1217 ocal_rise_edge2_taps <= #TCQ
'd0;
1218 ocal_rise_right_edge <= #TCQ
'd0;
1219 ocal_fall_edge1_found <= #TCQ
1'b0;
1220 ocal_fall_edge2_found <= #TCQ
1'b0;
1221 ocal_fall_edge1_taps <= #TCQ
'd0;
1222 ocal_fall_edge2_taps <= #TCQ
'd0;
1223 stg3_incdec_limit <= #TCQ
'd0;
1224 oclk_prech_req <= #TCQ
1'b1;
1225 if (
cnt_dqs_r ==
DQS_WIDTH-
1)
1226 wrlvl_final <= #TCQ
1'b1;
1227 if (
prech_done)
begin
1228 if (
cnt_dqs_r ==
DQS_WIDTH-
1)
1229 // If the last DQS group was just finished,
1230 // then end of calibration
1231 ocal_state_r <= #TCQ
OCAL_DONE;
1233 // Continue to next DQS group
1234 cnt_dqs_r <= #TCQ
cnt_dqs_r +
1;
1235 ocal_state_r <= #TCQ
OCAL_NEW_DQS_READ;
1236 stg3_tap_cnt <= #TCQ
oclkdelay_init_val;
1237 stg2_tap_cnt <= #TCQ
wl_po_fine_cnt_w[
cnt_dqs_r +
1'b1];
1243 ocal_final_cnt_r_calc <= #TCQ
1'b0;
1244 oclk_prech_req <= #TCQ
1'b0;
1245 po_stg23_sel <= #TCQ
1'b0;
1246 ocal_done_r <= #TCQ
1'b1;