AMC13
Firmwares for the different applications of the AMC13 uTCA board made at Boston University
Main Page
Design Unit List
Files
File List
All
Classes
Files
Variables
src
common
DDR
ddr3_1_9_a
phy
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
90
module
mig_7series_v1_9_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
(*
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
Generated on Sun Mar 6 2016 12:24:20 for AMC13 by
1.8.1