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
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 Wed Apr 18 2018 10:55:28 for AMC13 by
1.8.1