AMC13
Firmwares for the different applications of the AMC13 uTCA board made at Boston University
 All Classes Files Variables
mig_7series_v1_9_ddr_phy_oclkdelay_cal.v
1  //*****************************************************************************
2 // (c) Copyright 2009 - 2013 Xilinx, Inc. All rights reserved.
3 //
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
7 // laws.
8 //
9 // DISCLAIMER
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.
30 //
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.
44 //
45 // THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
46 // PART OF THIS FILE AT ALL TIMES.
47 //
48 //*****************************************************************************
49 // ____ ____
50 // / /\/ /
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
57 // \___\/\___\
58 //
59 //Device: 7 Series
60 //Design Name: DDR3 SDRAM
61 //Purpose: Center write DQS in write DQ valid window using Phaser_Out Stage3
62 // delay
63 //Reference:
64 //Revision History:
65 //*****************************************************************************
66 
67 `timescale 1ps/1ps
68 
70  (
71  parameter TCQ = 100,
72  parameter tCK = 2500,
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"
81  )
82  (
83  input clk,
84  input rst,
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
90  input phy_rddata_en,
91  input [2*nCK_PER_CLK*DQ_WIDTH-1:0] rd_data,
92  // Precharge done status from ddr_phy_init
93  input prech_done,
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
111  );
112 
113 
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;
122 
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";
128 
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;
150 
151 
152  integer i;
153 
154  reg oclk_init_delay_start_r;
155  reg [3:0] count;
156  reg delay_done;
157  reg delay_done_r1;
158  reg delay_done_r2;
159  reg delay_done_r3;
160  reg delay_done_r4;
161  reg [5:0] delay_cnt_r;
162  reg po_stg3_dec;
163 
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;
172 
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;
191  reg rd_active_r;
192  reg rd_active_r1;
193  reg rd_active_r2;
194  reg rd_active_r3;
195  reg rd_active_r4;
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;
216  //reg stable_eye_r;
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;
221  reg wait_cnt_en_r;
222  reg [3:0] wait_cnt_r;
223  reg cnt_next_state;
224  reg oclkdelay_calib_start_r;
225  reg [5:0] stg3_tap_cnt;
226  reg [5:0] stg3_incdec_limit;
227  reg stg3_dec2inc;
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;
232  reg stg3_dec;
233  reg stg3_dec_r;
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;
256  reg ocal_byte_done;
257  reg ocal_wrlvl_done;
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];
261  reg prech_done_r;
262  reg rise_win;
263  reg fall_win;
264 // timing registers
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;
270  reg stg3_limit;
271  wire [5:0] wl_po_fine_cnt_w[0:DQS_WIDTH-1];
272 
273  //**************************************************************************
274  // Debug signals
275  //**************************************************************************
276 
277  genvar dqs_i;
278  generate
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];
281  end
282  endgenerate
283 
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;
322 
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;
339 
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;
343 
344  always @(posedge clk)
345  oclk_init_delay_start_r <= #TCQ oclk_init_delay_start;
346 
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;
352  end
353 
354  always @(posedge clk) begin
355  if (rst)
356  po_stg3_dec <= #TCQ 1'b0;
357  else if ((count == 'd1) && (delay_cnt_r != 'd0))
358  po_stg3_dec <= #TCQ 1'b1;
359  else
360  po_stg3_dec <= #TCQ 1'b0;
361  end
362 
363  //po_stg3_incdec and po_en_stg3 asserted for all data byte lanes
364  always @(posedge clk) begin
365  if (rst) 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;
371  end else begin
372  po_stg3_incdec <= #TCQ 1'b0;
373  po_en_stg3 <= #TCQ 1'b0;
374  end
375  end
376 
377  // delay counter to count TAP_CNT cycles
378  always @(posedge clk) begin
379  // load delay counter with init value of TAP_CNT
380  if (rst)
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;
384  end
385 
386  // when all the ctl_lanes have their output phase shifted by 1/4 cycle, delay shifting is done.
387  always @(posedge clk) begin
388  if (rst) 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;
393  end
394  end
395 
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;
401  end
402 
403  //**************************************************************************
404  // OCLKDELAY Calibration
405  //**************************************************************************
406 
407  generate
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];
422  end
423  endgenerate
424 
425 
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;
437  end
438 
439 
440 
441  // Register outputs for improved timing.
442  // All bits in selected DQS group are checked in aggregate
443  generate
444  genvar mux_j;
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];
456  end
457  end
458  end
459  endgenerate
460 
461  always @(posedge clk)
462  if (((stg3_tap_cnt_eq_oclkdelay_init_val) && rd_active_r) |
463  rd_active_r4) begin
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;
472  end
473 
474 
475  // Each bit of each byte is compared with previous data to
476  // detect an edge
477  generate
478  genvar pt_j;
479 
480  if (nCK_PER_CLK == 4) begin: gen_pat_match_div4
481 
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));
486  end
487  end
488 
489  for (pt_j = 0; pt_j < DRAM_WIDTH; pt_j = pt_j + 1) begin: gen_pat_match
490 
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;
494  else
495  pat_match_rise0_r[pt_j] <= #TCQ 1'b0;
496 
497  if (sel_rd_fall0_r[pt_j] == prev_rd_fall0_r[pt_j])
498  pat_match_fall0_r[pt_j] <= #TCQ 1'b1;
499  else
500  pat_match_fall0_r[pt_j] <= #TCQ 1'b0;
501 
502  if (sel_rd_rise1_r[pt_j] == prev_rd_rise1_r[pt_j])
503  pat_match_rise1_r[pt_j] <= #TCQ 1'b1;
504  else
505  pat_match_rise1_r[pt_j] <= #TCQ 1'b0;
506 
507  if (sel_rd_fall1_r[pt_j] == prev_rd_fall1_r[pt_j])
508  pat_match_fall1_r[pt_j] <= #TCQ 1'b1;
509  else
510  pat_match_fall1_r[pt_j] <= #TCQ 1'b0;
511 
512  if (sel_rd_rise2_r[pt_j] == prev_rd_rise2_r[pt_j])
513  pat_match_rise2_r[pt_j] <= #TCQ 1'b1;
514  else
515  pat_match_rise2_r[pt_j] <= #TCQ 1'b0;
516 
517  if (sel_rd_fall2_r[pt_j] == prev_rd_fall2_r[pt_j])
518  pat_match_fall2_r[pt_j] <= #TCQ 1'b1;
519  else
520  pat_match_fall2_r[pt_j] <= #TCQ 1'b0;
521 
522  if (sel_rd_rise3_r[pt_j] == prev_rd_rise3_r[pt_j])
523  pat_match_rise3_r[pt_j] <= #TCQ 1'b1;
524  else
525  pat_match_rise3_r[pt_j] <= #TCQ 1'b0;
526 
527  if (sel_rd_fall3_r[pt_j] == prev_rd_fall3_r[pt_j])
528  pat_match_fall3_r[pt_j] <= #TCQ 1'b1;
529  else
530  pat_match_fall3_r[pt_j] <= #TCQ 1'b0;
531  end
532  end
533 
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;
552  end
553 
554  always @(posedge clk)
555  pat_data_match_valid_r1 <= #TCQ pat_data_match_valid_r;
556 
557  end else if (nCK_PER_CLK == 2) begin: gen_pat_match_div2
558 
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));
563  end
564  end
565 
566  for (pt_j = 0; pt_j < DRAM_WIDTH; pt_j = pt_j + 1) begin: gen_pat_match
567 
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;
571  else
572  pat_match_rise0_r[pt_j] <= #TCQ 1'b0;
573 
574  if (sel_rd_fall0_r[pt_j] == prev_rd_fall0_r[pt_j])
575  pat_match_fall0_r[pt_j] <= #TCQ 1'b1;
576  else
577  pat_match_fall0_r[pt_j] <= #TCQ 1'b0;
578 
579  if (sel_rd_rise1_r[pt_j] == prev_rd_rise1_r[pt_j])
580  pat_match_rise1_r[pt_j] <= #TCQ 1'b1;
581  else
582  pat_match_rise1_r[pt_j] <= #TCQ 1'b0;
583 
584  if (sel_rd_fall1_r[pt_j] == prev_rd_fall1_r[pt_j])
585  pat_match_fall1_r[pt_j] <= #TCQ 1'b1;
586  else
587  pat_match_fall1_r[pt_j] <= #TCQ 1'b0;
588  end
589 
590  end
591 
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;
602  end
603 
604  always @(posedge clk)
605  pat_data_match_valid_r1 <= #TCQ pat_data_match_valid_r;
606 
607  end
608  endgenerate
609 
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;
622  end
623 
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;
629  end
630 
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;
641  end
642 
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;
648  end
649 
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;
661  else
662  wait_cnt_en_r <= #TCQ 1'b0;
663 
664  always @(posedge clk)
665  if (!wait_cnt_en_r) begin
666  wait_cnt_r <= #TCQ 'b0;
667  cnt_next_state <= #TCQ 1'b0;
668  end else begin
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;
672  end else begin
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;
677  end
678  end
679 
680  always @(posedge clk) begin
681  if (rst) begin
682  for (i=0; i < DQS_WIDTH; i = i + 1) begin: rst_ocal_tap_cnt
683  ocal_tap_cnt_r[i] <= #TCQ 'b0;
684  end
685  end else if (stg3_dec_r && ~stg3_dec)
686  ocal_tap_cnt_r[cnt_dqs_r][5:0] <= #TCQ stg3_tap_cnt;
687  end
688 
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;
694  else if (prech_done)
695  prech_done_r <= #TCQ 1'b1;
696  end
697 
698 
699 
700 
701  // setting stg3_tap_cnt == oclkdelay_int_val
702 
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;
706  end else begin
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)
715 
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)
727 
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)
737 
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)
749 
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)
761 
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);
768  end
769  end
770 
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'
776 // D = '32' or '0'
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;
783  else
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;
791  end
792 
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;
799  else
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;
809  end
810 
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;
817  else
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;
821  else
822  ocal_final_cnt_r_mux_c <= #TCQ 'd1;
823  end
824 
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;
832  else
833  ocal_final_cnt_r_mux_d <= #TCQ 'd0;
834  end
835 
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;
842  end
843 
844  genvar dqs_q;
845  generate
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];
848  end
849  endgenerate
850 
851  // State Machine
852  always @(posedge clk) begin
853  if (rst) 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;
888  end else begin
889  case (ocal_state_r)
890 
891  OCAL_IDLE: begin
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];
896  end
897  end
898 
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;
904  end
905 
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;
929  end else begin
930  ocal_rise_edge1_found <= #TCQ 1'b1;
931  ocal_rise_edge1_found_timing <= #TCQ 1'b1;
932  end
933  end
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
941  // is detected
942  end else if (ocal_stg3_inc_en) begin
943  // Both edges found
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;
948  end else begin
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;
953  end
954  // Starting point in the valid window away from left edge
955  // Assuming starting point will not be in valid window close to
956  // left edge
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;
962  end else
963  ocal_state_r <= #TCQ OCAL_STG3_SEL;
964  end else
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;
972  end
973  end
974 
975  OCAL_STG3_SEL: begin
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;
980  end
981 
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;
991  end
992  end else begin
993  po_stg23_incdec <= #TCQ 1'b0;
994  if (stg3_dec)
995  ocal_dec_cnt <= #TCQ ocal_final_cnt_r;
996  end
997  end
998  end
999 
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;
1004  else
1005  ocal_state_r <= #TCQ OCAL_STG3_DEC;
1006  end
1007  end
1008 
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;
1019  end else
1020  ocal_state_r <= #TCQ OCAL_STG3_WAIT;
1021  end
1022 
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;
1028  else
1029  ocal_state_r <= #TCQ OCAL_DEC_DONE_WAIT;
1030  end
1031  end
1032 
1033  OCAL_DEC_DONE_WAIT: begin
1034  // Required to make sure that po_stg23_incdec
1035  // de-asserts some time after de-assertion of
1036  // po_en_stg23
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;
1044  end
1045  end
1046 
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;
1053  else begin
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;
1057  end
1058  end
1059  end
1060 
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;
1068  end
1069 
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;
1080  end else begin
1081  ocal_state_r <= #TCQ OCAL_NEXT_DQS;
1082  ocal_byte_done <= #TCQ 1'b0;
1083  end
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
1092  // write DQS and CK
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
1097  // write DQS and CK
1098  ocal_state_r <= #TCQ OCAL_STG2_DEC;
1099  end else begin
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;
1103  end
1104  end
1105  end
1106 
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;
1116  end else begin
1117  oclk_calib_resume <= #TCQ 1'b1;
1118  ocal_state_r <= #TCQ OCAL_NEW_DQS_WAIT;
1119  end
1120  end
1121 
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;
1134  else begin
1135  oclk_calib_resume <= #TCQ 1'b1;
1136  ocal_state_r <= #TCQ OCAL_NEW_DQS_WAIT;
1137  end
1138  end
1139 
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;
1153  else begin
1154  ocal_state_r <= #TCQ OCAL_NEW_DQS_READ;
1155  oclk_calib_resume <= #TCQ 1'b1;
1156  end
1157  end
1158  end
1159  end
1160 
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;
1166  end else
1167  ocal_final_cnt_r_calc <= #TCQ 1'b1;
1168  end
1169 
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;
1177  else
1178  ocal_state_r <= #TCQ OCAL_STG3_INC_WAIT;
1179  end
1180 
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;
1187  else begin
1188  ocal_state_r <= #TCQ OCAL_STG2_SEL;
1189  po_stg23_incdec <= #TCQ 1'b0;
1190  end
1191  end
1192  end
1193 
1194  OCAL_INC_DONE_WAIT: begin
1195  // Required to make sure that po_stg23_incdec
1196  // de-asserts some time after de-assertion of
1197  // po_en_stg23
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;
1202 
1203  po_stg23_incdec <= #TCQ 1'b0;
1204  end
1205  end
1206 
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;
1232  else begin
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];
1238  end
1239  end
1240  end
1241 
1242  OCAL_DONE: begin
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;
1247  end
1248  endcase
1249  end
1250  end
1251 
1252 endmodule