OpenCores
URL https://opencores.org/ocsvn/usb_fpga_2_14/usb_fpga_2_14/trunk

Subversion Repositories usb_fpga_2_14

[/] [usb_fpga_2_14/] [trunk/] [examples/] [memfifo/] [fpga-2.18/] [memfifo.srcs/] [sources_1/] [ip/] [mig_7series_0/] [mig_7series_0/] [user_design/] [rtl/] [phy/] [mig_7series_v2_3_ddr_phy_wrlvl.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 ZTEX
//*****************************************************************************
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
 
90
module mig_7series_v2_3_ddr_phy_wrlvl #
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
    output reg dqs_po_dec_done /* synthesis syn_maxfan = 2 */,
118
   output                       phy_ctl_rdy_dly,
119
    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
   (* max_fanout = 50 *) 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
                                                        // verilint STARC-2.2.3.3 off
822
              if(!wr_level_done_r & wr_level_start_r & wl_sm_start) begin
823
                if (SIM_CAL_OPTION == "FAST_CAL")
824
                  wl_state_r <= #TCQ WL_FINE_INC;
825
                else
826
                  wl_state_r <= #TCQ WL_INIT;
827
              end
828
           end
829
           // verilint STARC-2.2.3.3 on
830
           WL_INIT: begin
831
              wl_edge_detect_valid_r <= #TCQ 1'b0;
832
              inhibit_edge_detect_r  <= #TCQ 1'b1;
833
              wrlvl_rank_done_r      <= #TCQ 1'd0;
834
              //zero_tran_r <= #TCQ 1'b0;
835
              if (wrlvl_final)
836
                corse_cnt[dqs_count_w ]  <= #TCQ final_coarse_tap[dqs_count_w ];
837
              if (wrlvl_byte_redo) begin
838
                if (|wl_tap_count_r) begin
839
                  wl_state_r   <= #TCQ WL_FINE_DEC;
840
                  fine_dec_cnt <= #TCQ wl_tap_count_r;
841
                end else if ((corse_cnt[dqs_count_w] + wrlvl_redo_corse_inc) <= 'd7)
842
                  wl_state_r   <= #TCQ WL_CORSE_INC;
843
                else begin
844
                  wl_state_r   <= #TCQ WL_IDLE;
845
                  wrlvl_err    <= #TCQ 1'b1;
846
                end
847
              end else if(wl_sm_start)
848
                wl_state_r <= #TCQ WL_INIT_FINE_INC;
849
           end
850
 
851
           // Initially Phaser_Out fine delay taps incremented
852
           // until stable_cnt=14. A stable_cnt of 14 indicates
853
           // that rd_data_rise_wl_r=rd_data_previous_r for 14 fine
854
           // tap increments. This is done to inhibit false 0->1 
855
           // edge detection when DQS is initially aligned to the
856
           // negedge of CK
857
           WL_INIT_FINE_INC: begin
858
              wl_state_r   <= #TCQ WL_INIT_FINE_INC_WAIT1;
859
              wl_tap_count_r <= #TCQ wl_tap_count_r + 1'b1;
860
              final_corse_dec <= #TCQ 1'b0;
861
           end
862
 
863
           WL_INIT_FINE_INC_WAIT1: begin
864
              if (wl_sm_start)
865
                wl_state_r <= #TCQ WL_INIT_FINE_INC_WAIT;
866
           end
867
 
868
           // Case1: stable value of rd_data_previous_r=0 then
869
           // proceed to 0->1 edge detection.
870
           // Case2: stable value of rd_data_previous_r=1 then
871
           // decrement fine taps to '0' and proceed to 0->1
872
           // edge detection. Need to decrement in this case to
873
           // make sure a valid 0->1 transition was not left 
874
           // undetected. 
875
           WL_INIT_FINE_INC_WAIT: begin
876
              if (wl_sm_start) begin
877
                if (stable_cnt < 'd14)
878
                  wl_state_r   <= #TCQ WL_INIT_FINE_INC;
879
                else if (~rd_data_previous_r[dqs_count_r]) begin
880
                  wl_state_r             <= #TCQ WL_WAIT;
881
                  inhibit_edge_detect_r  <= #TCQ 1'b0;
882
                end else begin
883
                  wl_state_r   <= #TCQ WL_INIT_FINE_DEC;
884
                  fine_dec_cnt <= #TCQ wl_tap_count_r;
885
                end
886
              end
887
           end
888
 
889
           // Case2: stable value of rd_data_previous_r=1 then
890
           // decrement fine taps to '0' and proceed to 0->1
891
           // edge detection. Need to decrement in this case to
892
           // make sure a valid 0->1 transition was not left 
893
           // undetected.
894
           WL_INIT_FINE_DEC: begin
895
              wl_tap_count_r <= #TCQ 'd0;
896
              wl_state_r   <= #TCQ WL_INIT_FINE_DEC_WAIT1;
897
              if (fine_dec_cnt > 6'd0)
898
                fine_dec_cnt <= #TCQ fine_dec_cnt - 1;
899
              else
900
                fine_dec_cnt <= #TCQ fine_dec_cnt;
901
           end
902
 
903
           WL_INIT_FINE_DEC_WAIT1: begin
904
             if (incdec_wait_cnt == 'd8)
905
               wl_state_r   <= #TCQ WL_INIT_FINE_DEC_WAIT;
906
           end
907
 
908
           WL_INIT_FINE_DEC_WAIT: begin
909
              if (fine_dec_cnt > 6'd0) begin
910
                wl_state_r             <= #TCQ WL_INIT_FINE_DEC;
911
                inhibit_edge_detect_r  <= #TCQ 1'b1;
912
              end else begin
913
                wl_state_r             <= #TCQ WL_WAIT;
914
                inhibit_edge_detect_r  <= #TCQ 1'b0;
915
              end
916
           end
917
 
918
           // Inc DQS Phaser_Out Stage2 Fine Delay line
919
           WL_FINE_INC: begin
920
              wl_edge_detect_valid_r <= #TCQ 1'b0;
921
              if (SIM_CAL_OPTION == "FAST_CAL") begin
922
                wl_state_r <= #TCQ WL_FINE_INC_WAIT;
923
                if (fast_cal_fine_cnt > 'd0)
924
                  fast_cal_fine_cnt <= #TCQ fast_cal_fine_cnt - 1;
925
                else
926
                  fast_cal_fine_cnt <= #TCQ fast_cal_fine_cnt;
927
              end else if (wr_level_done_r5) begin
928
                wl_tap_count_r <= #TCQ 'd0;
929
                wl_state_r <= #TCQ WL_FINE_INC_WAIT;
930
                if (|fine_inc[dqs_count_w])
931
                      fine_inc[dqs_count_w] <= #TCQ fine_inc[dqs_count_w] - 1;
932
              end else begin
933
                wl_state_r <= #TCQ WL_WAIT;
934
                wl_tap_count_r <= #TCQ wl_tap_count_r + 1'b1;
935
              end
936
           end
937
 
938
           WL_FINE_INC_WAIT: begin
939
              if (SIM_CAL_OPTION == "FAST_CAL") begin
940
                if (fast_cal_fine_cnt > 'd0)
941
                  wl_state_r <= #TCQ WL_FINE_INC;
942
                else if (fast_cal_coarse_cnt > 'd0)
943
                  wl_state_r <= #TCQ WL_CORSE_INC;
944
                else
945
                  wl_state_r <= #TCQ WL_DQS_CNT;
946
              end else if (|fine_inc[dqs_count_w])
947
                wl_state_r   <= #TCQ WL_FINE_INC;
948
              else if (dqs_count_r == (DQS_WIDTH-1))
949
                wl_state_r   <= #TCQ WL_IDLE;
950
              else begin
951
                wl_state_r   <= #TCQ WL_2RANK_FINAL_TAP;
952
                dqs_count_r  <= #TCQ dqs_count_r + 1;
953
              end
954
           end
955
 
956
           WL_FINE_DEC: begin
957
              wl_edge_detect_valid_r <= #TCQ 1'b0;
958
              wl_tap_count_r <= #TCQ 'd0;
959
              wl_state_r   <= #TCQ WL_FINE_DEC_WAIT1;
960
              if (fine_dec_cnt > 6'd0)
961
                fine_dec_cnt <= #TCQ fine_dec_cnt - 1;
962
              else
963
                fine_dec_cnt <= #TCQ fine_dec_cnt;
964
           end
965
 
966
           WL_FINE_DEC_WAIT1: begin
967
             if (incdec_wait_cnt == 'd8)
968
               wl_state_r   <= #TCQ WL_FINE_DEC_WAIT;
969
           end
970
 
971
           WL_FINE_DEC_WAIT: begin
972
              if (fine_dec_cnt > 6'd0)
973
                wl_state_r   <= #TCQ WL_FINE_DEC;
974
              //else if (zero_tran_r)
975
              //  wl_state_r <= #TCQ WL_DQS_CNT;
976
              else if (dual_rnk_dec) begin
977
                if (|corse_dec[dqs_count_r])
978
                  wl_state_r <= #TCQ WL_CORSE_DEC;
979
                else
980
                  wl_state_r <= #TCQ WL_2RANK_DQS_CNT;
981
              end else if (wrlvl_byte_redo) begin
982
                if ((corse_cnt[dqs_count_w] + wrlvl_redo_corse_inc) <= 'd7)
983
                  wl_state_r <= #TCQ WL_CORSE_INC;
984
                else begin
985
                  wl_state_r <= #TCQ WL_IDLE;
986
                  wrlvl_err  <= #TCQ 1'b1;
987
                end
988
              end else
989
                wl_state_r <= #TCQ WL_CORSE_INC;
990
           end
991
 
992
           WL_CORSE_DEC: begin
993
              wl_state_r   <= #TCQ WL_CORSE_DEC_WAIT;
994
              dual_rnk_dec <= #TCQ 1'b0;
995
              if (|corse_dec[dqs_count_r])
996
                corse_dec[dqs_count_r] <= #TCQ corse_dec[dqs_count_r] - 1;
997
              else
998
                corse_dec[dqs_count_r]  <= #TCQ corse_dec[dqs_count_r];
999
           end
1000
 
1001
           WL_CORSE_DEC_WAIT: begin
1002
              if (wl_sm_start) begin
1003
              //if (|corse_dec[dqs_count_r])
1004
              //  wl_state_r <= #TCQ WL_CORSE_DEC;
1005
              if (|corse_dec[dqs_count_r])
1006
                wl_state_r <= #TCQ WL_CORSE_DEC_WAIT1;
1007
                else
1008
                wl_state_r <= #TCQ WL_2RANK_DQS_CNT;
1009
              end
1010
           end
1011
 
1012
           WL_CORSE_DEC_WAIT1: begin
1013
              if (wl_sm_start)
1014
                wl_state_r <= #TCQ WL_CORSE_DEC;
1015
           end
1016
 
1017
           WL_CORSE_INC: begin
1018
              wl_state_r <= #TCQ WL_CORSE_INC_WAIT_TMP;
1019
              if (SIM_CAL_OPTION == "FAST_CAL") begin
1020
                if (fast_cal_coarse_cnt > 'd0)
1021
                  fast_cal_coarse_cnt <= #TCQ fast_cal_coarse_cnt - 1;
1022
                else
1023
                  fast_cal_coarse_cnt <= #TCQ fast_cal_coarse_cnt;
1024
              end else if (wrlvl_byte_redo) begin
1025
                corse_cnt[dqs_count_w] <= #TCQ corse_cnt[dqs_count_w] + 1;
1026
                if (|wrlvl_redo_corse_inc)
1027
                  wrlvl_redo_corse_inc <= #TCQ wrlvl_redo_corse_inc - 1;
1028
              end else if (~wr_level_done_r5)
1029
                corse_cnt[dqs_count_r] <= #TCQ corse_cnt[dqs_count_r] + 1;
1030
              else if (|corse_inc[dqs_count_w])
1031
                corse_inc[dqs_count_w] <= #TCQ corse_inc[dqs_count_w] - 1;
1032
           end
1033
 
1034
           WL_CORSE_INC_WAIT_TMP: begin
1035
             if (incdec_wait_cnt == 'd8)
1036
             wl_state_r <= #TCQ WL_CORSE_INC_WAIT;
1037
           end
1038
 
1039
           WL_CORSE_INC_WAIT: begin
1040
              if (SIM_CAL_OPTION == "FAST_CAL") begin
1041
                if (fast_cal_coarse_cnt > 'd0)
1042
                  wl_state_r   <= #TCQ WL_CORSE_INC;
1043
                else
1044
                  wl_state_r <= #TCQ WL_DQS_CNT;
1045
              end else if (wrlvl_byte_redo) begin
1046
                if (|wrlvl_redo_corse_inc)
1047
                  wl_state_r   <= #TCQ WL_CORSE_INC;
1048
                else begin
1049
                  wl_state_r            <= #TCQ WL_INIT_FINE_INC;
1050
                  inhibit_edge_detect_r <= #TCQ 1'b1;
1051
                end
1052
              end else if (~wr_level_done_r5 && wl_sm_start)
1053
                wl_state_r <= #TCQ WL_CORSE_INC_WAIT1;
1054
              else if (wr_level_done_r5) begin
1055
                if (|corse_inc[dqs_count_r])
1056
                  wl_state_r   <= #TCQ WL_CORSE_INC;
1057
                else if (|fine_inc[dqs_count_w])
1058
                  wl_state_r   <= #TCQ WL_FINE_INC;
1059
                else if (dqs_count_r == (DQS_WIDTH-1))
1060
                  wl_state_r   <= #TCQ WL_IDLE;
1061
                else begin
1062
                  wl_state_r   <= #TCQ WL_2RANK_FINAL_TAP;
1063
                  dqs_count_r  <= #TCQ dqs_count_r + 1;
1064
                end
1065
              end
1066
           end
1067
 
1068
           WL_CORSE_INC_WAIT1: begin
1069
              if (wl_sm_start)
1070
                wl_state_r <= #TCQ WL_CORSE_INC_WAIT2;
1071
           end
1072
 
1073
           WL_CORSE_INC_WAIT2: begin
1074
             if (wl_sm_start)
1075
                wl_state_r <= #TCQ WL_WAIT;
1076
           end
1077
 
1078
           WL_WAIT: begin
1079
              if (wl_sm_start)
1080
              wl_state_r <= #TCQ WL_EDGE_CHECK;
1081
           end
1082
 
1083
           WL_EDGE_CHECK: begin // Look for the edge
1084
              if (wl_edge_detect_valid_r == 1'b0) begin
1085
                wl_state_r <= #TCQ WL_WAIT;
1086
                wl_edge_detect_valid_r <= #TCQ 1'b1;
1087
              end
1088
              // 0->1 transition detected with DQS
1089
              else if(rd_data_edge_detect_r[dqs_count_r] &&
1090
                      wl_edge_detect_valid_r)
1091
                begin
1092
                  wl_tap_count_r <= #TCQ wl_tap_count_r;
1093
                  if ((SIM_CAL_OPTION == "FAST_CAL") || (RANKS < 2) ||
1094
                      ~oclkdelay_calib_done)
1095
                    wl_state_r <= #TCQ WL_DQS_CNT;
1096
                  else
1097
                    wl_state_r <= #TCQ WL_2RANK_TAP_DEC;
1098
                end
1099
              // For initial writes check only upto 56 taps. Reserving the 
1100
              // remaining taps for OCLK calibration. 
1101
              else if((~wrlvl_tap_done_r) && (wl_tap_count_r > 6'd55)) begin
1102
                if (corse_cnt[dqs_count_r] < COARSE_TAPS) begin
1103
                  wl_state_r   <= #TCQ WL_FINE_DEC;
1104
                  fine_dec_cnt <= #TCQ wl_tap_count_r;
1105
                end  else begin
1106
                  wrlvl_err <= #TCQ 1'b1;
1107
                  wl_state_r   <= #TCQ WL_IDLE;
1108
                end
1109
              end else begin
1110
                  if (wl_tap_count_r < 6'd56)  //for reuse wrlvl for complex ocal              
1111
                    wl_state_r <= #TCQ WL_FINE_INC;
1112
                  else if (corse_cnt[dqs_count_r] < COARSE_TAPS) begin
1113
                    wl_state_r   <= #TCQ WL_FINE_DEC;
1114
                    fine_dec_cnt <= #TCQ wl_tap_count_r;
1115
                  end else begin
1116
                   wrlvl_err <= #TCQ 1'b1;
1117
                   wl_state_r   <= #TCQ WL_IDLE;
1118
                  end
1119
              end
1120
           end
1121
 
1122
           WL_2RANK_TAP_DEC: begin
1123
              wl_state_r    <= #TCQ WL_FINE_DEC;
1124
              fine_dec_cnt  <= #TCQ wl_tap_count_r;
1125
              for (m = 0; m < DQS_WIDTH; m = m + 1)
1126
                corse_dec[m] <= #TCQ corse_cnt[m];
1127
              wl_edge_detect_valid_r <= #TCQ 1'b0;
1128
              dual_rnk_dec <= #TCQ 1'b1;
1129
           end
1130
 
1131
           WL_DQS_CNT: begin
1132
              if ((SIM_CAL_OPTION == "FAST_CAL") ||
1133
                  (dqs_count_r == (DQS_WIDTH-1)) ||
1134
                  wrlvl_byte_redo) begin
1135
                dqs_count_r <= #TCQ dqs_count_r;
1136
                dq_cnt_inc  <= #TCQ 1'b0;
1137
              end else begin
1138
                dqs_count_r <= #TCQ dqs_count_r + 1'b1;
1139
                dq_cnt_inc  <= #TCQ 1'b1;
1140
              end
1141
              wl_state_r <= #TCQ WL_DQS_CHECK;
1142
              wl_edge_detect_valid_r <= #TCQ 1'b0;
1143
           end
1144
 
1145
           WL_2RANK_DQS_CNT: begin
1146
              if ((SIM_CAL_OPTION == "FAST_CAL") ||
1147
                 (dqs_count_r == (DQS_WIDTH-1))) begin
1148
                dqs_count_r <= #TCQ dqs_count_r;
1149
                dq_cnt_inc  <= #TCQ 1'b0;
1150
              end else begin
1151
                dqs_count_r <= #TCQ dqs_count_r + 1'b1;
1152
                dq_cnt_inc  <= #TCQ 1'b1;
1153
              end
1154
              wl_state_r <= #TCQ WL_DQS_CHECK;
1155
              wl_edge_detect_valid_r <= #TCQ 1'b0;
1156
              dual_rnk_dec <= #TCQ 1'b0;
1157
           end
1158
 
1159
           WL_DQS_CHECK: begin // check if all DQS have been calibrated
1160
              wl_tap_count_r <= #TCQ 'd0;
1161
              if (dq_cnt_inc == 1'b0)begin
1162
                wrlvl_rank_done_r <= #TCQ 1'd1;
1163
                for (t = 0; t < DQS_WIDTH; t = t + 1)
1164
                  corse_cnt[t] <= #TCQ 3'b0;
1165
                if ((SIM_CAL_OPTION == "FAST_CAL") || (RANKS < 2) || ~oclkdelay_calib_done) begin
1166
                  wl_state_r  <= #TCQ WL_IDLE;
1167
                  if (wrlvl_byte_redo)
1168
                    dqs_count_r <= #TCQ dqs_count_r;
1169
                  else
1170
                  dqs_count_r <= #TCQ 'd0;
1171
                end else if (rank_cnt_r == RANKS-1) begin
1172
                  dqs_count_r <= #TCQ dqs_count_r;
1173
                  if (RANKS > 1)
1174
                    wl_state_r  <= #TCQ WL_2RANK_FINAL_TAP;
1175
                  else
1176
                    wl_state_r  <= #TCQ WL_IDLE;
1177
                end else begin
1178
                  wl_state_r  <= #TCQ WL_INIT;
1179
                  dqs_count_r <= #TCQ 'd0;
1180
                end
1181
                if ((SIM_CAL_OPTION == "FAST_CAL") ||
1182
                    (rank_cnt_r == RANKS-1)) begin
1183
                  wr_level_done_r <= #TCQ 1'd1;
1184
                  rank_cnt_r      <= #TCQ 2'b00;
1185
                end else begin
1186
                  wr_level_done_r <= #TCQ 1'd0;
1187
                  rank_cnt_r      <= #TCQ rank_cnt_r + 1'b1;
1188
                end
1189
              end else
1190
                wl_state_r  <= #TCQ WL_INIT;
1191
           end
1192
 
1193
           WL_2RANK_FINAL_TAP: begin
1194
              if (wr_level_done_r4 && ~wr_level_done_r5) begin
1195
                for(u = 0; u < DQS_WIDTH; u = u + 1) begin
1196
                  corse_inc[u] <= #TCQ final_coarse_tap[u];
1197
                  fine_inc[u]  <= #TCQ final_val[u];
1198
                end
1199
                dqs_count_r    <= #TCQ 'd0;
1200
              end else if (wr_level_done_r5) begin
1201
                if (|corse_inc[dqs_count_r])
1202
                  wl_state_r   <= #TCQ WL_CORSE_INC;
1203
                else if (|fine_inc[dqs_count_w])
1204
                  wl_state_r   <= #TCQ WL_FINE_INC;
1205
              end
1206
           end
1207
        endcase
1208
     end
1209
   end // always @ (posedge clk)
1210
 
1211
endmodule
1212
 
1213
 
1214
 
1215
 
1216
 
1217
 
1218
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.