AMC13
Firmwares for the different applications of the AMC13 uTCA board made at Boston University
 All Classes Variables
mig_7series_v1_9_ddr_phy_wrlvl.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_wrlvl.v
55 // /___/ /\ Date Last Modified: $Date: 2011/06/24 14:49:00 $
56 // \ \ / \ Date Created: Mon Jun 23 2008
57 // \___\/\___\
58 //
59 //Device: 7 Series
60 //Design Name: DDR3 SDRAM
61 //Purpose:
62 // Memory initialization and overall master state control during
63 // initialization and calibration. Specifically, the following functions
64 // are performed:
65 // 1. Memory initialization (initial AR, mode register programming, etc.)
66 // 2. Initiating write leveling
67 // 3. Generate training pattern writes for read leveling. Generate
68 // memory readback for read leveling.
69 // This module has a DFI interface for providing control/address and write
70 // data to the rest of the PHY datapath during initialization/calibration.
71 // Once initialization is complete, control is passed to the MC.
72 // NOTES:
73 // 1. Multiple CS (multi-rank) not supported
74 // 2. DDR2 not supported
75 // 3. ODT not supported
76 //Reference:
77 //Revision History:
78 //*****************************************************************************
79 
80 /******************************************************************************
81 **$Id: ddr_phy_wrlvl.v,v 1.3 2011/06/24 14:49:00 mgeorge Exp $
82 **$Date: 2011/06/24 14:49:00 $
83 **$Author: mgeorge $
84 **$Revision: 1.3 $
85 **$Source: /devl/xcs/repo/env/Databases/ip/src2/O/mig_7series_v1_3/data/dlib/7series/ddr3_sdram/verilog/rtl/phy/ddr_phy_wrlvl.v,v $
86 *******************************************************************************/
87 
88 `timescale 1ps/1ps
89 
91  (
92  parameter TCQ = 100,
93  parameter DQS_CNT_WIDTH = 3,
94  parameter DQ_WIDTH = 64,
95  parameter DQS_WIDTH = 2,
96  parameter DRAM_WIDTH = 8,
97  parameter RANKS = 1,
98  parameter nCK_PER_CLK = 4,
99  parameter CLK_PERIOD = 4,
100  parameter SIM_CAL_OPTION = "NONE"
101  )
102  (
103  input clk,
104  input rst,
105  input phy_ctl_ready,
106  input wr_level_start,
107  input wl_sm_start,
108  input wrlvl_final,
109  input wrlvl_byte_redo,
110  input [DQS_CNT_WIDTH:0] wrcal_cnt,
111  input early1_data,
112  input early2_data,
113  input [DQS_CNT_WIDTH:0] oclkdelay_calib_cnt,
114  input oclkdelay_calib_done,
115  input [(DQ_WIDTH)-1:0] rd_data_rise0,
116  output reg wrlvl_byte_done,
117  (* keep = "true", max_fanout = 2 *) output reg dqs_po_dec_done /* synthesis syn_maxfan = 2 **/,
118  output phy_ctl_rdy_dly,
119  (* keep = "true", max_fanout = 2 *) output reg wr_level_done /* synthesis syn_maxfan = 2 **/,
120  // to phy_init for cs logic
121  output wrlvl_rank_done,
122  output done_dqs_tap_inc,
123  output [DQS_CNT_WIDTH:0] po_stg2_wl_cnt,
124  // Fine delay line used only during write leveling
125  // Inc/dec Phaser_Out fine delay line
126  output reg dqs_po_stg2_f_incdec,
127  // Enable Phaser_Out fine delay inc/dec
128  output reg dqs_po_en_stg2_f,
129  // Coarse delay line used during write leveling
130  // only if 64 taps of fine delay line were not
131  // sufficient to detect a 0->1 transition
132  // Inc Phaser_Out coarse delay line
133  output reg dqs_wl_po_stg2_c_incdec,
134  // Enable Phaser_Out coarse delay inc/dec
135  output reg dqs_wl_po_en_stg2_c,
136  // Read Phaser_Out delay value
137  input [8:0] po_counter_read_val,
138 // output reg dqs_wl_po_stg2_load,
139 // output reg [8:0] dqs_wl_po_stg2_reg_l,
140  // CK edge undetected
141  output reg wrlvl_err,
142  output reg [3*DQS_WIDTH-1:0] wl_po_coarse_cnt,
143  output reg [6*DQS_WIDTH-1:0] wl_po_fine_cnt,
144  // Debug ports
145  output [5:0] dbg_wl_tap_cnt,
146  output dbg_wl_edge_detect_valid,
147  output [(DQS_WIDTH)-1:0] dbg_rd_data_edge_detect,
148  output [DQS_CNT_WIDTH:0] dbg_dqs_count,
149  output [4:0] dbg_wl_state,
150  output [6*DQS_WIDTH-1:0] dbg_wrlvl_fine_tap_cnt,
151  output [3*DQS_WIDTH-1:0] dbg_wrlvl_coarse_tap_cnt,
152  output [255:0] dbg_phy_wrlvl
153  );
154 
155 
156  localparam WL_IDLE = 5'h0;
157  localparam WL_INIT = 5'h1;
158  localparam WL_INIT_FINE_INC = 5'h2;
159  localparam WL_INIT_FINE_INC_WAIT1= 5'h3;
160  localparam WL_INIT_FINE_INC_WAIT = 5'h4;
161  localparam WL_INIT_FINE_DEC = 5'h5;
162  localparam WL_INIT_FINE_DEC_WAIT = 5'h6;
163  localparam WL_FINE_INC = 5'h7;
164  localparam WL_WAIT = 5'h8;
165  localparam WL_EDGE_CHECK = 5'h9;
166  localparam WL_DQS_CHECK = 5'hA;
167  localparam WL_DQS_CNT = 5'hB;
168  localparam WL_2RANK_TAP_DEC = 5'hC;
169  localparam WL_2RANK_DQS_CNT = 5'hD;
170  localparam WL_FINE_DEC = 5'hE;
171  localparam WL_FINE_DEC_WAIT = 5'hF;
172  localparam WL_CORSE_INC = 5'h10;
173  localparam WL_CORSE_INC_WAIT = 5'h11;
174  localparam WL_CORSE_INC_WAIT1 = 5'h12;
175  localparam WL_CORSE_INC_WAIT2 = 5'h13;
176  localparam WL_CORSE_DEC = 5'h14;
177  localparam WL_CORSE_DEC_WAIT = 5'h15;
178  localparam WL_CORSE_DEC_WAIT1 = 5'h16;
179  localparam WL_FINE_INC_WAIT = 5'h17;
180  localparam WL_2RANK_FINAL_TAP = 5'h18;
181  localparam WL_INIT_FINE_DEC_WAIT1= 5'h19;
182  localparam WL_FINE_DEC_WAIT1 = 5'h1A;
183  localparam WL_CORSE_INC_WAIT_TMP = 5'h1B;
184 
185  localparam COARSE_TAPS = 7;
186 
187  localparam FAST_CAL_FINE = (CLK_PERIOD/nCK_PER_CLK <= 2500) ? 45 : 48;
188  localparam FAST_CAL_COARSE = (CLK_PERIOD/nCK_PER_CLK <= 2500) ? 1 : 2;
189  localparam REDO_COARSE = (CLK_PERIOD/nCK_PER_CLK <= 2500) ? 2 : 5;
190 
191 
192  integer i, j, k, l, p, q, r, s, t, m, n, u, v, w, x,y;
193 
194  reg phy_ctl_ready_r1;
195  reg phy_ctl_ready_r2;
196  reg phy_ctl_ready_r3;
197  reg phy_ctl_ready_r4;
198  reg phy_ctl_ready_r5;
199  reg phy_ctl_ready_r6;
200  reg [DQS_CNT_WIDTH:0] dqs_count_r;
201  reg [1:0] rank_cnt_r;
202  reg [DQS_WIDTH-1:0] rd_data_rise_wl_r;
203  reg [DQS_WIDTH-1:0] rd_data_previous_r;
204  reg [DQS_WIDTH-1:0] rd_data_edge_detect_r;
205  reg wr_level_done_r;
206  reg wrlvl_rank_done_r;
207  reg wr_level_start_r;
208  reg [4:0] wl_state_r, wl_state_r1;
209  reg inhibit_edge_detect_r;
210  reg wl_edge_detect_valid_r;
211  reg [5:0] wl_tap_count_r;
212  reg [5:0] fine_dec_cnt;
213  reg [5:0] fine_inc[0:DQS_WIDTH-1]; // DQS_WIDTH number of counters 6-bit each
214  reg [2:0] corse_dec[0:DQS_WIDTH-1];
215  reg [2:0] corse_inc[0:DQS_WIDTH-1];
216  reg dq_cnt_inc;
217  reg [3:0] stable_cnt;
218  reg flag_ck_negedge;
219  //reg past_negedge;
220  reg flag_init;
221  reg [2:0] corse_cnt[0:DQS_WIDTH-1];
222  reg [3*DQS_WIDTH-1:0] corse_cnt_dbg;
223  reg [2:0] wl_corse_cnt[0:RANKS-1][0:DQS_WIDTH-1];
224  //reg [3*DQS_WIDTH-1:0] coarse_tap_inc;
225  reg [2:0] final_coarse_tap[0:DQS_WIDTH-1];
226  reg [5:0] add_smallest[0:DQS_WIDTH-1];
227  reg [5:0] add_largest[0:DQS_WIDTH-1];
228  //reg [6*DQS_WIDTH-1:0] fine_tap_inc;
229  //reg [6*DQS_WIDTH-1:0] fine_tap_dec;
230  reg wr_level_done_r1;
231  reg wr_level_done_r2;
232  reg wr_level_done_r3;
233  reg wr_level_done_r4;
234  reg wr_level_done_r5;
235  reg [5:0] wl_dqs_tap_count_r[0:RANKS-1][0:DQS_WIDTH-1];
236  reg [5:0] smallest[0:DQS_WIDTH-1];
237  reg [5:0] largest[0:DQS_WIDTH-1];
238  reg [5:0] final_val[0:DQS_WIDTH-1];
239  reg [5:0] po_dec_cnt[0:DQS_WIDTH-1];
240  reg done_dqs_dec;
241  reg [8:0] po_rdval_cnt;
242  reg po_cnt_dec;
243  reg po_dec_done;
244  reg dual_rnk_dec;
245  wire [DQS_CNT_WIDTH+2:0] dqs_count_w;
246  reg [5:0] fast_cal_fine_cnt;
247  reg [2:0] fast_cal_coarse_cnt;
248  reg wrlvl_byte_redo_r;
249  reg [2:0] wrlvl_redo_corse_inc;
250  reg wrlvl_final_r;
251  reg final_corse_dec;
252  wire [DQS_CNT_WIDTH+2:0] oclk_count_w;
253  reg wrlvl_tap_done_r ;
254  reg [3:0] wait_cnt;
255  reg [3:0] incdec_wait_cnt;
256 
257 
258 
259  // Debug ports
260  assign dbg_wl_edge_detect_valid = wl_edge_detect_valid_r;
261  assign dbg_rd_data_edge_detect = rd_data_edge_detect_r;
262  assign dbg_wl_tap_cnt = wl_tap_count_r;
263  assign dbg_dqs_count = dqs_count_r;
264  assign dbg_wl_state = wl_state_r;
265  assign dbg_wrlvl_fine_tap_cnt = wl_po_fine_cnt;
266  assign dbg_wrlvl_coarse_tap_cnt = wl_po_coarse_cnt;
267 
268  always @(*) begin
269  for (v = 0; v < DQS_WIDTH; v = v + 1)
270  corse_cnt_dbg[3*v+:3] = corse_cnt[v];
271  end
272 
273  assign dbg_phy_wrlvl[0+:27] = corse_cnt_dbg;
274  assign dbg_phy_wrlvl[27+:5] = wl_state_r;
275  assign dbg_phy_wrlvl[32+:4] = dqs_count_r;
276  assign dbg_phy_wrlvl[36+:9] = rd_data_rise_wl_r;
277  assign dbg_phy_wrlvl[45+:9] = rd_data_previous_r;
278  assign dbg_phy_wrlvl[54+:4] = stable_cnt;
279  assign dbg_phy_wrlvl[58] = 'd0;
280  assign dbg_phy_wrlvl[59] = flag_ck_negedge;
281 
282  assign dbg_phy_wrlvl [60] = wl_edge_detect_valid_r;
283  assign dbg_phy_wrlvl [61+:6] = wl_tap_count_r;
284  assign dbg_phy_wrlvl [67+:9] = rd_data_edge_detect_r;
285  assign dbg_phy_wrlvl [76+:54] = wl_po_fine_cnt;
286  assign dbg_phy_wrlvl [130+:27] = wl_po_coarse_cnt;
287 
288 
289 
290  //**************************************************************************
291  // DQS count to hard PHY during write leveling using Phaser_OUT Stage2 delay
292  //**************************************************************************
293  assign po_stg2_wl_cnt = dqs_count_r;
294 
295  assign wrlvl_rank_done = wrlvl_rank_done_r;
296 
297  assign done_dqs_tap_inc = done_dqs_dec;
298 
299  assign phy_ctl_rdy_dly = phy_ctl_ready_r6;
300 
301  always @(posedge clk) begin
302  phy_ctl_ready_r1 <= #TCQ phy_ctl_ready;
303  phy_ctl_ready_r2 <= #TCQ phy_ctl_ready_r1;
304  phy_ctl_ready_r3 <= #TCQ phy_ctl_ready_r2;
305  phy_ctl_ready_r4 <= #TCQ phy_ctl_ready_r3;
306  phy_ctl_ready_r5 <= #TCQ phy_ctl_ready_r4;
307  phy_ctl_ready_r6 <= #TCQ phy_ctl_ready_r5;
308  wrlvl_byte_redo_r <= #TCQ wrlvl_byte_redo;
309  wrlvl_final_r <= #TCQ wrlvl_final;
310  if ((wrlvl_byte_redo && ~wrlvl_byte_redo_r) ||
311  (wrlvl_final && ~wrlvl_final_r))
312  wr_level_done <= #TCQ 1'b0;
313  else
314  wr_level_done <= #TCQ done_dqs_dec;
315  end
316 
317 // Status signal that will be asserted once the first
318 // pass of write leveling is done.
319  always @(posedge clk) begin
320  if(rst) begin
321  wrlvl_tap_done_r <= #TCQ 1'b0 ;
322  end else begin
323  if(wrlvl_tap_done_r == 1'b0) begin
324  if(oclkdelay_calib_done) begin
325  wrlvl_tap_done_r <= #TCQ 1'b1 ;
326  end
327  end
328  end
329  end
330 
331  always @(posedge clk) begin
332  if (rst || po_cnt_dec)
333  wait_cnt <= #TCQ 'd8;
334  else if (phy_ctl_ready_r6 && (wait_cnt > 'd0))
335  wait_cnt <= #TCQ wait_cnt - 1;
336  end
337 
338  always @(posedge clk) begin
339  if (rst) begin
340  po_rdval_cnt <= #TCQ 'd0;
341  end else if (phy_ctl_ready_r5 && ~phy_ctl_ready_r6) begin
342  po_rdval_cnt <= #TCQ po_counter_read_val;
343  end else if (po_rdval_cnt > 'd0) begin
344  if (po_cnt_dec)
345  po_rdval_cnt <= #TCQ po_rdval_cnt - 1;
346  else
347  po_rdval_cnt <= #TCQ po_rdval_cnt;
348  end else if (po_rdval_cnt == 'd0) begin
349  po_rdval_cnt <= #TCQ po_rdval_cnt;
350  end
351  end
352 
353  always @(posedge clk) begin
354  if (rst || (po_rdval_cnt == 'd0))
355  po_cnt_dec <= #TCQ 1'b0;
356  else if (phy_ctl_ready_r6 && (po_rdval_cnt > 'd0) && (wait_cnt == 'd1))
357  po_cnt_dec <= #TCQ 1'b1;
358  else
359  po_cnt_dec <= #TCQ 1'b0;
360  end
361 
362  always @(posedge clk) begin
363  if (rst)
364  po_dec_done <= #TCQ 1'b0;
365  else if (((po_cnt_dec == 'd1) && (po_rdval_cnt == 'd1)) ||
366  (phy_ctl_ready_r6 && (po_rdval_cnt == 'd0))) begin
367  po_dec_done <= #TCQ 1'b1;
368  end
369  end
370 
371 
372  always @(posedge clk) begin
373  dqs_po_dec_done <= #TCQ po_dec_done;
374  wr_level_done_r1 <= #TCQ wr_level_done_r;
375  wr_level_done_r2 <= #TCQ wr_level_done_r1;
376  wr_level_done_r3 <= #TCQ wr_level_done_r2;
377  wr_level_done_r4 <= #TCQ wr_level_done_r3;
378  wr_level_done_r5 <= #TCQ wr_level_done_r4;
379  for (l = 0; l < DQS_WIDTH; l = l + 1) begin
380  wl_po_coarse_cnt[3*l+:3] <= #TCQ final_coarse_tap[l];
381  if ((RANKS == 1) || ~oclkdelay_calib_done)
382  wl_po_fine_cnt[6*l+:6] <= #TCQ smallest[l];
383  else
384  wl_po_fine_cnt[6*l+:6] <= #TCQ final_val[l];
385  end
386  end
387 
388  generate
389  if (RANKS == 2) begin: dual_rank
390  always @(posedge clk) begin
391  if (rst || (wrlvl_byte_redo && ~wrlvl_byte_redo_r) ||
392  (wrlvl_final && ~wrlvl_final_r))
393  done_dqs_dec <= #TCQ 1'b0;
394  else if ((SIM_CAL_OPTION == "FAST_CAL") || ~oclkdelay_calib_done)
395  done_dqs_dec <= #TCQ wr_level_done_r;
396  else if (wr_level_done_r5 && (wl_state_r == WL_IDLE))
397  done_dqs_dec <= #TCQ 1'b1;
398  end
399  end else begin: single_rank
400  always @(posedge clk) begin
401  if (rst || (wrlvl_byte_redo && ~wrlvl_byte_redo_r) ||
402  (wrlvl_final && ~wrlvl_final_r))
403  done_dqs_dec <= #TCQ 1'b0;
404  else if (~oclkdelay_calib_done)
405  done_dqs_dec <= #TCQ wr_level_done_r;
406  else if (wr_level_done_r3 && ~wr_level_done_r4)
407  done_dqs_dec <= #TCQ 1'b1;
408  end
409  end
410  endgenerate
411 
412  always @(posedge clk)
413  if (rst || (wrlvl_byte_redo && ~wrlvl_byte_redo_r))
414  wrlvl_byte_done <= #TCQ 1'b0;
415  else if (wrlvl_byte_redo && wr_level_done_r3 && ~wr_level_done_r4)
416  wrlvl_byte_done <= #TCQ 1'b1;
417 
418  // Storing DQS tap values at the end of each DQS write leveling
419  always @(posedge clk) begin
420  if (rst) begin
421  for (k = 0; k < RANKS; k = k + 1) begin: rst_wl_dqs_tap_count_loop
422  for (n = 0; n < DQS_WIDTH; n = n + 1) begin
423  wl_corse_cnt[k][n] <= #TCQ 'b0;
424  wl_dqs_tap_count_r[k][n] <= #TCQ 'b0;
425  end
426  end
427  end else if ((wl_state_r == WL_DQS_CNT) | (wl_state_r == WL_WAIT) |
428  (wl_state_r == WL_FINE_DEC_WAIT1) |
429  (wl_state_r == WL_2RANK_TAP_DEC)) begin
430  wl_dqs_tap_count_r[rank_cnt_r][dqs_count_r] <= #TCQ wl_tap_count_r;
431  wl_corse_cnt[rank_cnt_r][dqs_count_r] <= #TCQ corse_cnt[dqs_count_r];
432  end else if ((SIM_CAL_OPTION == "FAST_CAL") & (wl_state_r == WL_DQS_CHECK)) begin
433  for (p = 0; p < RANKS; p = p +1) begin: dqs_tap_rank_cnt
434  for(q = 0; q < DQS_WIDTH; q = q +1) begin: dqs_tap_dqs_cnt
435  wl_dqs_tap_count_r[p][q] <= #TCQ wl_tap_count_r;
436  wl_corse_cnt[p][q] <= #TCQ corse_cnt[0];
437  end
438  end
439  end
440  end
441 
442  // Convert coarse delay to fine taps in case of unequal number of coarse
443  // taps between ranks. Assuming a difference of 1 coarse tap counts
444  // between ranks. A common fine and coarse tap value must be used for both ranks
445  // because Phaser_Out has only one rank register.
446  // Coarse tap1 = period(ps)*93/360 = 34 fine taps
447  // Other coarse taps = period(ps)*103/360 = 38 fine taps
448 
449  generate
450  genvar cnt;
451  if (RANKS == 2) begin // Dual rank
452  for(cnt = 0; cnt < DQS_WIDTH; cnt = cnt +1) begin: coarse_dqs_cnt
453  always @(posedge clk) begin
454  if (rst) begin
455  //coarse_tap_inc[3*cnt+:3] <= #TCQ 'b0;
456  add_smallest[cnt] <= #TCQ 'd0;
457  add_largest[cnt] <= #TCQ 'd0;
458  final_coarse_tap[cnt] <= #TCQ 'd0;
459  end else if (wr_level_done_r1 & ~wr_level_done_r2) begin
460  if (~oclkdelay_calib_done) begin
461  for(y = 0 ; y < DQS_WIDTH; y = y+1) begin
462  final_coarse_tap[y] <= #TCQ wl_corse_cnt[0][y];
463  add_smallest[y] <= #TCQ 'd0;
464  add_largest[y] <= #TCQ 'd0;
465  end
466  end else
467  if (wl_corse_cnt[0][cnt] == wl_corse_cnt[1][cnt]) begin
468  // Both ranks have use the same number of coarse delay taps.
469  // No conversion of coarse tap to fine taps required.
470  //coarse_tap_inc[3*cnt+:3] <= #TCQ wl_corse_cnt[1][3*cnt+:3];
471  final_coarse_tap[cnt] <= #TCQ wl_corse_cnt[1][cnt];
472  add_smallest[cnt] <= #TCQ 'd0;
473  add_largest[cnt] <= #TCQ 'd0;
474  end else if (wl_corse_cnt[0][cnt] < wl_corse_cnt[1][cnt]) begin
475  // Rank 0 uses fewer coarse delay taps than rank1.
476  // conversion of coarse tap to fine taps required for rank1.
477  // The final coarse count will the smaller value.
478  //coarse_tap_inc[3*cnt+:3] <= #TCQ wl_corse_cnt[1][3*cnt+:3] - 1;
479  final_coarse_tap[cnt] <= #TCQ wl_corse_cnt[1][cnt] - 1;
480  if (|wl_corse_cnt[0][cnt])
481  // Coarse tap 2 or higher being converted to fine taps
482  // This will be added to 'largest' value in final_val
483  // computation
484  add_largest[cnt] <= #TCQ 'd38;
485  else
486  // Coarse tap 1 being converted to fine taps
487  // This will be added to 'largest' value in final_val
488  // computation
489  add_largest[cnt] <= #TCQ 'd34;
490  end else if (wl_corse_cnt[0][cnt] > wl_corse_cnt[1][cnt]) begin
491  // This may be an unlikely scenario in a real system.
492  // Rank 0 uses more coarse delay taps than rank1.
493  // conversion of coarse tap to fine taps required.
494  //coarse_tap_inc[3*cnt+:3] <= #TCQ 'd0;
495  final_coarse_tap[cnt] <= #TCQ wl_corse_cnt[1][cnt];
496  if (|wl_corse_cnt[1][cnt])
497  // Coarse tap 2 or higher being converted to fine taps
498  // This will be added to 'smallest' value in final_val
499  // computation
500  add_smallest[cnt] <= #TCQ 'd38;
501  else
502  // Coarse tap 1 being converted to fine taps
503  // This will be added to 'smallest' value in
504  // final_val computation
505  add_smallest[cnt] <= #TCQ 'd34;
506  end
507  end
508  end
509  end
510  end else begin
511  // Single rank
512  always @(posedge clk) begin
513  //coarse_tap_inc <= #TCQ 'd0;
514  for(w = 0; w < DQS_WIDTH; w = w + 1) begin
515  final_coarse_tap[w] <= #TCQ wl_corse_cnt[0][w];
516  add_smallest[w] <= #TCQ 'd0;
517  add_largest[w] <= #TCQ 'd0;
518  end
519  end
520  end
521  endgenerate
522 
523 
524  // Determine delay value for DQS in multirank system
525  // Assuming delay value is the smallest for rank 0 DQS
526  // and largest delay value for rank 4 DQS
527  // Set to smallest + ((largest-smallest)/2)
528  always @(posedge clk) begin
529  if (rst) begin
530  for(x = 0; x < DQS_WIDTH; x = x +1) begin
531  smallest[x] <= #TCQ 'b0;
532  largest[x] <= #TCQ 'b0;
533  end
534  end else if ((wl_state_r == WL_DQS_CNT) & wrlvl_byte_redo) begin
535  smallest[dqs_count_r] <= #TCQ wl_dqs_tap_count_r[0][dqs_count_r];
536  largest[dqs_count_r] <= #TCQ wl_dqs_tap_count_r[0][dqs_count_r];
537  end else if ((wl_state_r == WL_DQS_CNT) |
538  (wl_state_r == WL_2RANK_TAP_DEC)) begin
539  smallest[dqs_count_r] <= #TCQ wl_dqs_tap_count_r[0][dqs_count_r];
540  largest[dqs_count_r] <= #TCQ wl_dqs_tap_count_r[RANKS-1][dqs_count_r];
541  end else if (((SIM_CAL_OPTION == "FAST_CAL") |
542  (~oclkdelay_calib_done & ~wrlvl_byte_redo)) &
543  wr_level_done_r1 & ~wr_level_done_r2) begin
544  for(i = 0; i < DQS_WIDTH; i = i +1) begin: smallest_dqs
545  smallest[i] <= #TCQ wl_dqs_tap_count_r[0][i];
546  largest[i] <= #TCQ wl_dqs_tap_count_r[0][i];
547  end
548  end
549  end
550 
551 
552 // final_val to be used for all DQSs in all ranks
553  genvar wr_i;
554  generate
555  for (wr_i = 0; wr_i < DQS_WIDTH; wr_i = wr_i +1) begin: gen_final_tap
556  always @(posedge clk) begin
557  if (rst)
558  final_val[wr_i] <= #TCQ 'b0;
559  else if (wr_level_done_r2 && ~wr_level_done_r3) begin
560  if (~oclkdelay_calib_done)
561  final_val[wr_i] <= #TCQ (smallest[wr_i] + add_smallest[wr_i]);
562  else if ((smallest[wr_i] + add_smallest[wr_i]) <
563  (largest[wr_i] + add_largest[wr_i]))
564  final_val[wr_i] <= #TCQ ((smallest[wr_i] + add_smallest[wr_i]) +
565  (((largest[wr_i] + add_largest[wr_i]) -
566  (smallest[wr_i] + add_smallest[wr_i]))/2));
567  else if ((smallest[wr_i] + add_smallest[wr_i]) >
568  (largest[wr_i] + add_largest[wr_i]))
569  final_val[wr_i] <= #TCQ ((largest[wr_i] + add_largest[wr_i]) +
570  (((smallest[wr_i] + add_smallest[wr_i]) -
571  (largest[wr_i] + add_largest[wr_i]))/2));
572  else if ((smallest[wr_i] + add_smallest[wr_i]) ==
573  (largest[wr_i] + add_largest[wr_i]))
574  final_val[wr_i] <= #TCQ (largest[wr_i] + add_largest[wr_i]);
575  end
576  end
577  end
578  endgenerate
579 
580 // // fine tap inc/dec value for all DQSs in all ranks
581 // genvar dqs_i;
582 // generate
583 // for (dqs_i = 0; dqs_i < DQS_WIDTH; dqs_i = dqs_i +1) begin: gen_fine_tap
584 // always @(posedge clk) begin
585 // if (rst)
586 // fine_tap_inc[6*dqs_i+:6] <= #TCQ 'd0;
587 // //fine_tap_dec[6*dqs_i+:6] <= #TCQ 'd0;
588 // else if (wr_level_done_r3 && ~wr_level_done_r4) begin
589 // fine_tap_inc[6*dqs_i+:6] <= #TCQ final_val[6*dqs_i+:6];
590 // //fine_tap_dec[6*dqs_i+:6] <= #TCQ 'd0;
591 // end
592 // end
593 // endgenerate
594 
595 
596  // Inc/Dec Phaser_Out stage 2 fine delay line
597  always @(posedge clk) begin
598  if (rst) begin
599  // Fine delay line used only during write leveling
600  dqs_po_stg2_f_incdec <= #TCQ 1'b0;
601  dqs_po_en_stg2_f <= #TCQ 1'b0;
602  // Dec Phaser_Out fine delay (1)before write leveling,
603  // (2)if no 0 to 1 transition detected with 63 fine delay taps, or
604  // (3)dual rank case where fine taps for the first rank need to be 0
605  end else if (po_cnt_dec || (wl_state_r == WL_INIT_FINE_DEC) ||
606  (wl_state_r == WL_FINE_DEC)) begin
607  dqs_po_stg2_f_incdec <= #TCQ 1'b0;
608  dqs_po_en_stg2_f <= #TCQ 1'b1;
609  // Inc Phaser_Out fine delay during write leveling
610  end else if ((wl_state_r == WL_INIT_FINE_INC) ||
611  (wl_state_r == WL_FINE_INC)) begin
612  dqs_po_stg2_f_incdec <= #TCQ 1'b1;
613  dqs_po_en_stg2_f <= #TCQ 1'b1;
614  end else begin
615  dqs_po_stg2_f_incdec <= #TCQ 1'b0;
616  dqs_po_en_stg2_f <= #TCQ 1'b0;
617  end
618  end
619 
620 
621  // Inc Phaser_Out stage 2 Coarse delay line
622  always @(posedge clk) begin
623  if (rst) begin
624  // Coarse delay line used during write leveling
625  // only if no 0->1 transition undetected with 64
626  // fine delay line taps
627  dqs_wl_po_stg2_c_incdec <= #TCQ 1'b0;
628  dqs_wl_po_en_stg2_c <= #TCQ 1'b0;
629  end else if (wl_state_r == WL_CORSE_INC) begin
630  // Inc Phaser_Out coarse delay during write leveling
631  dqs_wl_po_stg2_c_incdec <= #TCQ 1'b1;
632  dqs_wl_po_en_stg2_c <= #TCQ 1'b1;
633  end else begin
634  dqs_wl_po_stg2_c_incdec <= #TCQ 1'b0;
635  dqs_wl_po_en_stg2_c <= #TCQ 1'b0;
636  end
637  end
638 
639 
640  // only storing the rise data for checking. The data comming back during
641  // write leveling will be a static value. Just checking for rise data is
642  // enough.
643 
644 genvar rd_i;
645 generate
646  for(rd_i = 0; rd_i < DQS_WIDTH; rd_i = rd_i +1)begin: gen_rd
647  always @(posedge clk)
648  rd_data_rise_wl_r[rd_i] <=
649  #TCQ |rd_data_rise0[(rd_i*DRAM_WIDTH)+DRAM_WIDTH-1:rd_i*DRAM_WIDTH];
650  end
651 endgenerate
652 
653 
654  // storing the previous data for checking later.
655  always @(posedge clk)begin
656  if ((wl_state_r == WL_INIT) || //(wl_state_r == WL_INIT_FINE_INC_WAIT) ||
657  //(wl_state_r == WL_INIT_FINE_INC_WAIT1) ||
658  ((wl_state_r1 == WL_INIT_FINE_INC_WAIT) & (wl_state_r == WL_INIT_FINE_INC)) ||
659  (wl_state_r == WL_FINE_DEC) || (wl_state_r == WL_FINE_DEC_WAIT1) || (wl_state_r == WL_FINE_DEC_WAIT) ||
660  (wl_state_r == WL_CORSE_INC) || (wl_state_r == WL_CORSE_INC_WAIT) || (wl_state_r == WL_CORSE_INC_WAIT_TMP) ||
661  (wl_state_r == WL_CORSE_INC_WAIT1) || (wl_state_r == WL_CORSE_INC_WAIT2) ||
662  ((wl_state_r == WL_EDGE_CHECK) & (wl_edge_detect_valid_r)))
663  rd_data_previous_r <= #TCQ rd_data_rise_wl_r;
664  end
665 
666  // changed stable count from 3 to 7 because of fine tap resolution
667  always @(posedge clk)begin
668  if (rst | (wl_state_r == WL_DQS_CNT) |
669  (wl_state_r == WL_2RANK_TAP_DEC) |
670  (wl_state_r == WL_FINE_DEC) |
671  (rd_data_previous_r[dqs_count_r] != rd_data_rise_wl_r[dqs_count_r]) |
672  (wl_state_r1 == WL_INIT_FINE_DEC))
673  stable_cnt <= #TCQ 'd0;
674  else if ((wl_tap_count_r > 6'd0) &
675  (((wl_state_r == WL_EDGE_CHECK) & (wl_edge_detect_valid_r)) |
676  ((wl_state_r1 == WL_INIT_FINE_INC_WAIT) & (wl_state_r == WL_INIT_FINE_INC)))) begin
677  if ((rd_data_previous_r[dqs_count_r] == rd_data_rise_wl_r[dqs_count_r])
678  & (stable_cnt < 'd14))
679  stable_cnt <= #TCQ stable_cnt + 1;
680  end
681  end
682 
683  // Signal to ensure that flag_ck_negedge does not incorrectly assert
684  // when DQS is very close to CK rising edge
685  //always @(posedge clk) begin
686  // if (rst | (wl_state_r == WL_DQS_CNT) |
687  // (wl_state_r == WL_DQS_CHECK) | wr_level_done_r)
688  // past_negedge <= #TCQ 1'b0;
689  // else if (~flag_ck_negedge && ~rd_data_previous_r[dqs_count_r] &&
690  // (stable_cnt == 'd0) && ((wl_state_r == WL_CORSE_INC_WAIT1) |
691  // (wl_state_r == WL_CORSE_INC_WAIT2)))
692  // past_negedge <= #TCQ 1'b1;
693  //end
694 
695  // Flag to indicate negedge of CK detected and ignore 0->1 transitions
696  // in this region
697  always @(posedge clk)begin
698  if (rst | (wl_state_r == WL_DQS_CNT) |
699  (wl_state_r == WL_DQS_CHECK) | wr_level_done_r |
700  (wl_state_r1 == WL_INIT_FINE_DEC))
701  flag_ck_negedge <= #TCQ 1'd0;
702  else if ((rd_data_previous_r[dqs_count_r] && ((stable_cnt > 'd0) |
703  (wl_state_r == WL_FINE_DEC) | (wl_state_r == WL_FINE_DEC_WAIT) | (wl_state_r == WL_FINE_DEC_WAIT1))) |
704  (wl_state_r == WL_CORSE_INC))
705  flag_ck_negedge <= #TCQ 1'd1;
706  else if (~rd_data_previous_r[dqs_count_r] && (stable_cnt == 'd14))
707  //&& flag_ck_negedge)
708  flag_ck_negedge <= #TCQ 1'd0;
709  end
710 
711  // Flag to inhibit rd_data_edge_detect_r before stable DQ
712  always @(posedge clk) begin
713  if (rst)
714  flag_init <= #TCQ 1'b1;
715  else if ((wl_state_r == WL_WAIT) && ((wl_state_r1 == WL_INIT_FINE_INC_WAIT) ||
716  (wl_state_r1 == WL_INIT_FINE_DEC_WAIT)))
717  flag_init <= #TCQ 1'b0;
718  end
719 
720  //checking for transition from 0 to 1
721  always @(posedge clk)begin
722  if (rst | flag_ck_negedge | flag_init | (wl_tap_count_r < 'd1) |
723  inhibit_edge_detect_r)
724  rd_data_edge_detect_r <= #TCQ {DQS_WIDTH{1'b0}};
725  else if (rd_data_edge_detect_r[dqs_count_r] == 1'b1) begin
726  if ((wl_state_r == WL_FINE_DEC) || (wl_state_r == WL_FINE_DEC_WAIT) || (wl_state_r == WL_FINE_DEC_WAIT1) ||
727  (wl_state_r == WL_CORSE_INC) || (wl_state_r == WL_CORSE_INC_WAIT) || (wl_state_r == WL_CORSE_INC_WAIT_TMP) ||
728  (wl_state_r == WL_CORSE_INC_WAIT1) || (wl_state_r == WL_CORSE_INC_WAIT2))
729  rd_data_edge_detect_r <= #TCQ {DQS_WIDTH{1'b0}};
730  else
731  rd_data_edge_detect_r <= #TCQ rd_data_edge_detect_r;
732  end else if (rd_data_previous_r[dqs_count_r] && (stable_cnt < 'd14))
733  rd_data_edge_detect_r <= #TCQ {DQS_WIDTH{1'b0}};
734  else
735  rd_data_edge_detect_r <= #TCQ (~rd_data_previous_r & rd_data_rise_wl_r);
736  end
737 
738 
739 
740  // registring the write level start signal
741  always@(posedge clk) begin
742  wr_level_start_r <= #TCQ wr_level_start;
743  end
744 
745  // Assign dqs_count_r to dqs_count_w to perform the shift operation
746  // instead of multiply operation
747  assign dqs_count_w = {2'b00, dqs_count_r};
748 
749  assign oclk_count_w = {2'b00, oclkdelay_calib_cnt};
750 
751  always @(posedge clk) begin
752  if (rst)
753  incdec_wait_cnt <= #TCQ 'd0;
754  else if ((wl_state_r == WL_FINE_DEC_WAIT1) ||
755  (wl_state_r == WL_INIT_FINE_DEC_WAIT1) ||
756  (wl_state_r == WL_CORSE_INC_WAIT_TMP))
757  incdec_wait_cnt <= #TCQ incdec_wait_cnt + 1;
758  else
759  incdec_wait_cnt <= #TCQ 'd0;
760  end
761 
762 
763  // state machine to initiate the write leveling sequence
764  // The state machine operates on one byte at a time.
765  // It will increment the delays to the DQS OSERDES
766  // and sample the DQ from the memory. When it detects
767  // a transition from 1 to 0 then the write leveling is considered
768  // done.
769  always @(posedge clk) begin
770  if(rst)begin
771  wrlvl_err <= #TCQ 1'b0;
772  wr_level_done_r <= #TCQ 1'b0;
773  wrlvl_rank_done_r <= #TCQ 1'b0;
774  dqs_count_r <= #TCQ {DQS_CNT_WIDTH+1{1'b0}};
775  dq_cnt_inc <= #TCQ 1'b1;
776  rank_cnt_r <= #TCQ 2'b00;
777  wl_state_r <= #TCQ WL_IDLE;
778  wl_state_r1 <= #TCQ WL_IDLE;
779  inhibit_edge_detect_r <= #TCQ 1'b1;
780  wl_edge_detect_valid_r <= #TCQ 1'b0;
781  wl_tap_count_r <= #TCQ 6'd0;
782  fine_dec_cnt <= #TCQ 6'd0;
783  for (r = 0; r < DQS_WIDTH; r = r + 1) begin
784  fine_inc[r] <= #TCQ 6'b0;
785  corse_dec[r] <= #TCQ 3'b0;
786  corse_inc[r] <= #TCQ 3'b0;
787  corse_cnt[r] <= #TCQ 3'b0;
788  end
789  dual_rnk_dec <= #TCQ 1'b0;
790  fast_cal_fine_cnt <= #TCQ FAST_CAL_FINE;
791  fast_cal_coarse_cnt <= #TCQ FAST_CAL_COARSE;
792  final_corse_dec <= #TCQ 1'b0;
793  //zero_tran_r <= #TCQ 1'b0;
794  wrlvl_redo_corse_inc <= #TCQ 'd0;
795  end else begin
796  wl_state_r1 <= #TCQ wl_state_r;
797  case (wl_state_r)
798 
799  WL_IDLE: begin
800  wrlvl_rank_done_r <= #TCQ 1'd0;
801  inhibit_edge_detect_r <= #TCQ 1'b1;
802  if (wrlvl_byte_redo && ~wrlvl_byte_redo_r) begin
803  wr_level_done_r <= #TCQ 1'b0;
804  dqs_count_r <= #TCQ wrcal_cnt;
805  corse_cnt[wrcal_cnt] <= #TCQ final_coarse_tap[wrcal_cnt];
806  wl_tap_count_r <= #TCQ smallest[wrcal_cnt];
807  if (early1_data &&
808  (((final_coarse_tap[wrcal_cnt] < 'd6) && (CLK_PERIOD/nCK_PER_CLK <= 2500)) ||
809  ((final_coarse_tap[wrcal_cnt] < 'd3) && (CLK_PERIOD/nCK_PER_CLK > 2500))))
810  wrlvl_redo_corse_inc <= #TCQ REDO_COARSE;
811  else if (early2_data && (final_coarse_tap[wrcal_cnt] < 'd2))
812  wrlvl_redo_corse_inc <= #TCQ 3'd6;
813  else begin
814  wl_state_r <= #TCQ WL_IDLE;
815  wrlvl_err <= #TCQ 1'b1;
816  end
817  end else if (wrlvl_final && ~wrlvl_final_r) begin
818  wr_level_done_r <= #TCQ 1'b0;
819  dqs_count_r <= #TCQ 'd0;
820  end
821  if(!wr_level_done_r & wr_level_start_r & wl_sm_start) begin
822  if (SIM_CAL_OPTION == "FAST_CAL")
823  wl_state_r <= #TCQ WL_FINE_INC;
824  else
825  wl_state_r <= #TCQ WL_INIT;
826  end
827  end
828 
829  WL_INIT: begin
830  wl_edge_detect_valid_r <= #TCQ 1'b0;
831  inhibit_edge_detect_r <= #TCQ 1'b1;
832  wrlvl_rank_done_r <= #TCQ 1'd0;
833  //zero_tran_r <= #TCQ 1'b0;
834  if (wrlvl_final)
835  corse_cnt[dqs_count_w ] <= #TCQ final_coarse_tap[dqs_count_w ];
836  if (wrlvl_byte_redo) begin
837  if (|wl_tap_count_r) begin
838  wl_state_r <= #TCQ WL_FINE_DEC;
839  fine_dec_cnt <= #TCQ wl_tap_count_r;
840  end else if ((corse_cnt[dqs_count_w] + wrlvl_redo_corse_inc) <= 'd7)
841  wl_state_r <= #TCQ WL_CORSE_INC;
842  else begin
843  wl_state_r <= #TCQ WL_IDLE;
844  wrlvl_err <= #TCQ 1'b1;
845  end
846  end else if(wl_sm_start)
847  wl_state_r <= #TCQ WL_INIT_FINE_INC;
848  end
849 
850  // Initially Phaser_Out fine delay taps incremented
851  // until stable_cnt=14. A stable_cnt of 14 indicates
852  // that rd_data_rise_wl_r=rd_data_previous_r for 14 fine
853  // tap increments. This is done to inhibit false 0->1
854  // edge detection when DQS is initially aligned to the
855  // negedge of CK
856  WL_INIT_FINE_INC: begin
857  wl_state_r <= #TCQ WL_INIT_FINE_INC_WAIT1;
858  wl_tap_count_r <= #TCQ wl_tap_count_r + 1'b1;
859  final_corse_dec <= #TCQ 1'b0;
860  end
861 
862  WL_INIT_FINE_INC_WAIT1: begin
863  if (wl_sm_start)
864  wl_state_r <= #TCQ WL_INIT_FINE_INC_WAIT;
865  end
866 
867  // Case1: stable value of rd_data_previous_r=0 then
868  // proceed to 0->1 edge detection.
869  // Case2: stable value of rd_data_previous_r=1 then
870  // decrement fine taps to '0' and proceed to 0->1
871  // edge detection. Need to decrement in this case to
872  // make sure a valid 0->1 transition was not left
873  // undetected.
874  WL_INIT_FINE_INC_WAIT: begin
875  if (wl_sm_start) begin
876  if (stable_cnt < 'd14)
877  wl_state_r <= #TCQ WL_INIT_FINE_INC;
878  else if (~rd_data_previous_r[dqs_count_r]) begin
879  wl_state_r <= #TCQ WL_WAIT;
880  inhibit_edge_detect_r <= #TCQ 1'b0;
881  end else begin
882  wl_state_r <= #TCQ WL_INIT_FINE_DEC;
883  fine_dec_cnt <= #TCQ wl_tap_count_r;
884  end
885  end
886  end
887 
888  // Case2: stable value of rd_data_previous_r=1 then
889  // decrement fine taps to '0' and proceed to 0->1
890  // edge detection. Need to decrement in this case to
891  // make sure a valid 0->1 transition was not left
892  // undetected.
893  WL_INIT_FINE_DEC: begin
894  wl_tap_count_r <= #TCQ 'd0;
895  wl_state_r <= #TCQ WL_INIT_FINE_DEC_WAIT1;
896  if (fine_dec_cnt > 6'd0)
897  fine_dec_cnt <= #TCQ fine_dec_cnt - 1;
898  else
899  fine_dec_cnt <= #TCQ fine_dec_cnt;
900  end
901 
902  WL_INIT_FINE_DEC_WAIT1: begin
903  if (incdec_wait_cnt == 'd8)
904  wl_state_r <= #TCQ WL_INIT_FINE_DEC_WAIT;
905  end
906 
907  WL_INIT_FINE_DEC_WAIT: begin
908  if (fine_dec_cnt > 6'd0) begin
909  wl_state_r <= #TCQ WL_INIT_FINE_DEC;
910  inhibit_edge_detect_r <= #TCQ 1'b1;
911  end else begin
912  wl_state_r <= #TCQ WL_WAIT;
913  inhibit_edge_detect_r <= #TCQ 1'b0;
914  end
915  end
916 
917  // Inc DQS Phaser_Out Stage2 Fine Delay line
918  WL_FINE_INC: begin
919  wl_edge_detect_valid_r <= #TCQ 1'b0;
920  if (SIM_CAL_OPTION == "FAST_CAL") begin
921  wl_state_r <= #TCQ WL_FINE_INC_WAIT;
922  if (fast_cal_fine_cnt > 'd0)
923  fast_cal_fine_cnt <= #TCQ fast_cal_fine_cnt - 1;
924  else
925  fast_cal_fine_cnt <= #TCQ fast_cal_fine_cnt;
926  end else if (wr_level_done_r5) begin
927  wl_tap_count_r <= #TCQ 'd0;
928  wl_state_r <= #TCQ WL_FINE_INC_WAIT;
929  if (|fine_inc[dqs_count_w])
930  fine_inc[dqs_count_w] <= #TCQ fine_inc[dqs_count_w] - 1;
931  end else begin
932  wl_state_r <= #TCQ WL_WAIT;
933  wl_tap_count_r <= #TCQ wl_tap_count_r + 1'b1;
934  end
935  end
936 
937  WL_FINE_INC_WAIT: begin
938  if (SIM_CAL_OPTION == "FAST_CAL") begin
939  if (fast_cal_fine_cnt > 'd0)
940  wl_state_r <= #TCQ WL_FINE_INC;
941  else if (fast_cal_coarse_cnt > 'd0)
942  wl_state_r <= #TCQ WL_CORSE_INC;
943  else
944  wl_state_r <= #TCQ WL_DQS_CNT;
945  end else if (|fine_inc[dqs_count_w])
946  wl_state_r <= #TCQ WL_FINE_INC;
947  else if (dqs_count_r == (DQS_WIDTH-1))
948  wl_state_r <= #TCQ WL_IDLE;
949  else begin
950  wl_state_r <= #TCQ WL_2RANK_FINAL_TAP;
951  dqs_count_r <= #TCQ dqs_count_r + 1;
952  end
953  end
954 
955  WL_FINE_DEC: begin
956  wl_edge_detect_valid_r <= #TCQ 1'b0;
957  wl_tap_count_r <= #TCQ 'd0;
958  wl_state_r <= #TCQ WL_FINE_DEC_WAIT1;
959  if (fine_dec_cnt > 6'd0)
960  fine_dec_cnt <= #TCQ fine_dec_cnt - 1;
961  else
962  fine_dec_cnt <= #TCQ fine_dec_cnt;
963  end
964 
965  WL_FINE_DEC_WAIT1: begin
966  if (incdec_wait_cnt == 'd8)
967  wl_state_r <= #TCQ WL_FINE_DEC_WAIT;
968  end
969 
970  WL_FINE_DEC_WAIT: begin
971  if (fine_dec_cnt > 6'd0)
972  wl_state_r <= #TCQ WL_FINE_DEC;
973  //else if (zero_tran_r)
974  // wl_state_r <= #TCQ WL_DQS_CNT;
975  else if (dual_rnk_dec) begin
976  if (|corse_dec[dqs_count_r])
977  wl_state_r <= #TCQ WL_CORSE_DEC;
978  else
979  wl_state_r <= #TCQ WL_2RANK_DQS_CNT;
980  end else if (wrlvl_byte_redo) begin
981  if ((corse_cnt[dqs_count_w] + wrlvl_redo_corse_inc) <= 'd7)
982  wl_state_r <= #TCQ WL_CORSE_INC;
983  else begin
984  wl_state_r <= #TCQ WL_IDLE;
985  wrlvl_err <= #TCQ 1'b1;
986  end
987  end else
988  wl_state_r <= #TCQ WL_CORSE_INC;
989  end
990 
991  WL_CORSE_DEC: begin
992  wl_state_r <= #TCQ WL_CORSE_DEC_WAIT;
993  dual_rnk_dec <= #TCQ 1'b0;
994  if (|corse_dec[dqs_count_r])
995  corse_dec[dqs_count_r] <= #TCQ corse_dec[dqs_count_r] - 1;
996  else
997  corse_dec[dqs_count_r] <= #TCQ corse_dec[dqs_count_r];
998  end
999 
1000  WL_CORSE_DEC_WAIT: begin
1001  if (wl_sm_start) begin
1002  //if (|corse_dec[dqs_count_r])
1003  // wl_state_r <= #TCQ WL_CORSE_DEC;
1004  if (|corse_dec[dqs_count_r])
1005  wl_state_r <= #TCQ WL_CORSE_DEC_WAIT1;
1006  else
1007  wl_state_r <= #TCQ WL_2RANK_DQS_CNT;
1008  end
1009  end
1010 
1011  WL_CORSE_DEC_WAIT1: begin
1012  if (wl_sm_start)
1013  wl_state_r <= #TCQ WL_CORSE_DEC;
1014  end
1015 
1016  WL_CORSE_INC: begin
1017  wl_state_r <= #TCQ WL_CORSE_INC_WAIT_TMP;
1018  if (SIM_CAL_OPTION == "FAST_CAL") begin
1019  if (fast_cal_coarse_cnt > 'd0)
1020  fast_cal_coarse_cnt <= #TCQ fast_cal_coarse_cnt - 1;
1021  else
1022  fast_cal_coarse_cnt <= #TCQ fast_cal_coarse_cnt;
1023  end else if (wrlvl_byte_redo) begin
1024  corse_cnt[dqs_count_w] <= #TCQ corse_cnt[dqs_count_w] + 1;
1025  if (|wrlvl_redo_corse_inc)
1026  wrlvl_redo_corse_inc <= #TCQ wrlvl_redo_corse_inc - 1;
1027  end else if (~wr_level_done_r5)
1028  corse_cnt[dqs_count_r] <= #TCQ corse_cnt[dqs_count_r] + 1;
1029  else if (|corse_inc[dqs_count_w])
1030  corse_inc[dqs_count_w] <= #TCQ corse_inc[dqs_count_w] - 1;
1031  end
1032 
1033  WL_CORSE_INC_WAIT_TMP: begin
1034  if (incdec_wait_cnt == 'd8)
1035  wl_state_r <= #TCQ WL_CORSE_INC_WAIT;
1036  end
1037 
1038  WL_CORSE_INC_WAIT: begin
1039  if (SIM_CAL_OPTION == "FAST_CAL") begin
1040  if (fast_cal_coarse_cnt > 'd0)
1041  wl_state_r <= #TCQ WL_CORSE_INC;
1042  else
1043  wl_state_r <= #TCQ WL_DQS_CNT;
1044  end else if (wrlvl_byte_redo) begin
1045  if (|wrlvl_redo_corse_inc)
1046  wl_state_r <= #TCQ WL_CORSE_INC;
1047  else begin
1048  wl_state_r <= #TCQ WL_INIT_FINE_INC;
1049  inhibit_edge_detect_r <= #TCQ 1'b1;
1050  end
1051  end else if (~wr_level_done_r5 && wl_sm_start)
1052  wl_state_r <= #TCQ WL_CORSE_INC_WAIT1;
1053  else if (wr_level_done_r5) begin
1054  if (|corse_inc[dqs_count_r])
1055  wl_state_r <= #TCQ WL_CORSE_INC;
1056  else if (|fine_inc[dqs_count_w])
1057  wl_state_r <= #TCQ WL_FINE_INC;
1058  else if (dqs_count_r == (DQS_WIDTH-1))
1059  wl_state_r <= #TCQ WL_IDLE;
1060  else begin
1061  wl_state_r <= #TCQ WL_2RANK_FINAL_TAP;
1062  dqs_count_r <= #TCQ dqs_count_r + 1;
1063  end
1064  end
1065  end
1066 
1067  WL_CORSE_INC_WAIT1: begin
1068  if (wl_sm_start)
1069  wl_state_r <= #TCQ WL_CORSE_INC_WAIT2;
1070  end
1071 
1072  WL_CORSE_INC_WAIT2: begin
1073  if (wl_sm_start)
1074  wl_state_r <= #TCQ WL_WAIT;
1075  end
1076 
1077  WL_WAIT: begin
1078  if (wl_sm_start)
1079  wl_state_r <= #TCQ WL_EDGE_CHECK;
1080  end
1081 
1082  WL_EDGE_CHECK: begin // Look for the edge
1083  if (wl_edge_detect_valid_r == 1'b0) begin
1084  wl_state_r <= #TCQ WL_WAIT;
1085  wl_edge_detect_valid_r <= #TCQ 1'b1;
1086  end
1087  // 0->1 transition detected with DQS
1088  else if(rd_data_edge_detect_r[dqs_count_r] &&
1089  wl_edge_detect_valid_r)
1090  begin
1091  wl_tap_count_r <= #TCQ wl_tap_count_r;
1092  if ((SIM_CAL_OPTION == "FAST_CAL") || (RANKS < 2) ||
1093  ~oclkdelay_calib_done)
1094  wl_state_r <= #TCQ WL_DQS_CNT;
1095  else
1096  wl_state_r <= #TCQ WL_2RANK_TAP_DEC;
1097  end
1098  // For initial writes check only upto 56 taps. Reserving the
1099  // remaining taps for OCLK calibration.
1100  else if((~wrlvl_tap_done_r) && (wl_tap_count_r > 6'd55)) begin
1101  if (corse_cnt[dqs_count_r] < COARSE_TAPS) begin
1102  wl_state_r <= #TCQ WL_FINE_DEC;
1103  fine_dec_cnt <= #TCQ wl_tap_count_r;
1104  end else begin
1105  wrlvl_err <= #TCQ 1'b1;
1106  wl_state_r <= #TCQ WL_IDLE;
1107  end
1108  end else begin
1109  if (wl_tap_count_r < 6'd63)
1110  wl_state_r <= #TCQ WL_FINE_INC;
1111  else if (corse_cnt[dqs_count_r] < COARSE_TAPS) begin
1112  wl_state_r <= #TCQ WL_FINE_DEC;
1113  fine_dec_cnt <= #TCQ wl_tap_count_r;
1114  end else begin
1115  wrlvl_err <= #TCQ 1'b1;
1116  wl_state_r <= #TCQ WL_IDLE;
1117  end
1118  end
1119  end
1120 
1121  WL_2RANK_TAP_DEC: begin
1122  wl_state_r <= #TCQ WL_FINE_DEC;
1123  fine_dec_cnt <= #TCQ wl_tap_count_r;
1124  for (m = 0; m < DQS_WIDTH; m = m + 1)
1125  corse_dec[m] <= #TCQ corse_cnt[m];
1126  wl_edge_detect_valid_r <= #TCQ 1'b0;
1127  dual_rnk_dec <= #TCQ 1'b1;
1128  end
1129 
1130  WL_DQS_CNT: begin
1131  if ((SIM_CAL_OPTION == "FAST_CAL") ||
1132  (dqs_count_r == (DQS_WIDTH-1)) ||
1133  wrlvl_byte_redo) begin
1134  dqs_count_r <= #TCQ dqs_count_r;
1135  dq_cnt_inc <= #TCQ 1'b0;
1136  end else begin
1137  dqs_count_r <= #TCQ dqs_count_r + 1'b1;
1138  dq_cnt_inc <= #TCQ 1'b1;
1139  end
1140  wl_state_r <= #TCQ WL_DQS_CHECK;
1141  wl_edge_detect_valid_r <= #TCQ 1'b0;
1142  end
1143 
1144  WL_2RANK_DQS_CNT: begin
1145  if ((SIM_CAL_OPTION == "FAST_CAL") ||
1146  (dqs_count_r == (DQS_WIDTH-1))) begin
1147  dqs_count_r <= #TCQ dqs_count_r;
1148  dq_cnt_inc <= #TCQ 1'b0;
1149  end else begin
1150  dqs_count_r <= #TCQ dqs_count_r + 1'b1;
1151  dq_cnt_inc <= #TCQ 1'b1;
1152  end
1153  wl_state_r <= #TCQ WL_DQS_CHECK;
1154  wl_edge_detect_valid_r <= #TCQ 1'b0;
1155  dual_rnk_dec <= #TCQ 1'b0;
1156  end
1157 
1158  WL_DQS_CHECK: begin // check if all DQS have been calibrated
1159  wl_tap_count_r <= #TCQ 'd0;
1160  if (dq_cnt_inc == 1'b0)begin
1161  wrlvl_rank_done_r <= #TCQ 1'd1;
1162  for (t = 0; t < DQS_WIDTH; t = t + 1)
1163  corse_cnt[t] <= #TCQ 3'b0;
1164  if ((SIM_CAL_OPTION == "FAST_CAL") || (RANKS < 2) || ~oclkdelay_calib_done) begin
1165  wl_state_r <= #TCQ WL_IDLE;
1166  if (wrlvl_byte_redo)
1167  dqs_count_r <= #TCQ dqs_count_r;
1168  else
1169  dqs_count_r <= #TCQ 'd0;
1170  end else if (rank_cnt_r == RANKS-1) begin
1171  dqs_count_r <= #TCQ dqs_count_r;
1172  if (RANKS > 1)
1173  wl_state_r <= #TCQ WL_2RANK_FINAL_TAP;
1174  else
1175  wl_state_r <= #TCQ WL_IDLE;
1176  end else begin
1177  wl_state_r <= #TCQ WL_INIT;
1178  dqs_count_r <= #TCQ 'd0;
1179  end
1180  if ((SIM_CAL_OPTION == "FAST_CAL") ||
1181  (rank_cnt_r == RANKS-1)) begin
1182  wr_level_done_r <= #TCQ 1'd1;
1183  rank_cnt_r <= #TCQ 2'b00;
1184  end else begin
1185  wr_level_done_r <= #TCQ 1'd0;
1186  rank_cnt_r <= #TCQ rank_cnt_r + 1'b1;
1187  end
1188  end else
1189  wl_state_r <= #TCQ WL_INIT;
1190  end
1191 
1192  WL_2RANK_FINAL_TAP: begin
1193  if (wr_level_done_r4 && ~wr_level_done_r5) begin
1194  for(u = 0; u < DQS_WIDTH; u = u + 1) begin
1195  corse_inc[u] <= #TCQ final_coarse_tap[u];
1196  fine_inc[u] <= #TCQ final_val[u];
1197  end
1198  dqs_count_r <= #TCQ 'd0;
1199  end else if (wr_level_done_r5) begin
1200  if (|corse_inc[dqs_count_r])
1201  wl_state_r <= #TCQ WL_CORSE_INC;
1202  else if (|fine_inc[dqs_count_w])
1203  wl_state_r <= #TCQ WL_FINE_INC;
1204  end
1205  end
1206  endcase
1207  end
1208  end // always @ (posedge clk)
1209 
1210 endmodule
1211 
1212 
1213 
1214 
1215 
1216 
1217