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_prbs_rdlvl.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:
53
// \ \ Application: MIG
54
// / / Filename: ddr_phy_prbs_rdlvl.v
55
// /___/ /\ Date Last Modified: $Date: 2011/06/24 14:49:00 $
56
// \ \ / \ Date Created:
57
// \___\/\___\
58
//
59
//Device: 7 Series
60
//Design Name: DDR3 SDRAM
61
//Purpose:
62
// PRBS Read leveling calibration logic
63
// NOTES:
64
// 1. Window detection with PRBS pattern.
65
//Reference:
66
//Revision History:
67
//*****************************************************************************
68
69
/******************************************************************************
70
**$Id: ddr_phy_prbs_rdlvl.v,v 1.2 2011/06/24 14:49:00 mgeorge Exp $
71
**$Date: 2011/06/24 14:49:00 $
72
**$Author: mgeorge $
73
**$Revision: 1.2 $
74
**$Source: /devl/xcs/repo/env/Databases/ip/src2/O/mig_7series_v1_3/data/dlib/7series/ddr3_sdram/verilog/rtl/phy/ddr_phy_prbs_rdlvl.v,v $
75
*******************************************************************************/
76
77
`timescale
1ps/1ps
78
79
module
mig_7series_v1_9_ddr_phy_prbs_rdlvl
#
80
(
81
parameter
TCQ
=
100
,
// clk->out delay (sim only)
82
parameter
nCK_PER_CLK
=
2
,
// # of memory clocks per CLK
83
parameter
DQ_WIDTH
=
64
,
// # of DQ (data)
84
parameter
DQS_CNT_WIDTH
=
3
,
// = ceil(log2(DQS_WIDTH))
85
parameter
DQS_WIDTH
=
8
,
// # of DQS (strobe)
86
parameter
DRAM_WIDTH
=
8
,
// # of DQ per DQS
87
parameter
RANKS
=
1
,
// # of DRAM ranks
88
parameter
SIM_CAL_OPTION
=
"NONE"
,
// Skip various calibration steps
89
parameter
PRBS_WIDTH
=
8
// PRBS generator output width
90
)
91
(
92
input
clk
,
93
input
rst
,
94
// Calibration status, control signals
95
input
prbs_rdlvl_start
,
96
output
reg
prbs_rdlvl_done
,
97
output
reg
prbs_last_byte_done
,
98
output
reg
prbs_rdlvl_prech_req
,
99
input
prech_done
,
100
input
phy_if_empty
,
101
// Captured data in fabric clock domain
102
input
[
2
*
nCK_PER_CLK
*
DQ_WIDTH
-
1
:
0
]
rd_data
,
103
//Expected data from PRBS generator
104
input
[
2
*
nCK_PER_CLK
*
PRBS_WIDTH
-
1
:
0
]
compare_data
,
105
// Decrement initial Phaser_IN Fine tap delay
106
input
[
5
:
0
]
pi_counter_read_val
,
107
// Stage 1 calibration outputs
108
output
reg
pi_en_stg2_f
,
109
output
reg
pi_stg2_f_incdec
,
110
output
[
255
:
0
]
dbg_prbs_rdlvl
,
111
output
[
DQS_CNT_WIDTH
:
0
]
pi_stg2_prbs_rdlvl_cnt
112
);
113
114
115
116
117
localparam
[
5
:
0
]
PRBS_IDLE
=
6'h00
;
118
localparam
[
5
:
0
]
PRBS_NEW_DQS_WAIT
=
6'h01
;
119
localparam
[
5
:
0
]
PRBS_PAT_COMPARE
=
6'h02
;
120
localparam
[
5
:
0
]
PRBS_DEC_DQS
=
6'h03
;
121
localparam
[
5
:
0
]
PRBS_DEC_DQS_WAIT
=
6'h04
;
122
localparam
[
5
:
0
]
PRBS_INC_DQS
=
6'h05
;
123
localparam
[
5
:
0
]
PRBS_INC_DQS_WAIT
=
6'h06
;
124
localparam
[
5
:
0
]
PRBS_CALC_TAPS
=
6'h07
;
125
localparam
[
5
:
0
]
PRBS_TAP_CHECK
=
6'h08
;
126
localparam
[
5
:
0
]
PRBS_NEXT_DQS
=
6'h09
;
127
localparam
[
5
:
0
]
PRBS_NEW_DQS_PREWAIT
=
6'h0A
;
128
localparam
[
5
:
0
]
PRBS_DONE
=
6'h0B
;
129
130
131
localparam
[
11
:
0
]
NUM_SAMPLES_CNT
= (
SIM_CAL_OPTION
==
"NONE"
) ?
12'hFFF
:
12'h001
;
132
localparam
[
11
:
0
]
NUM_SAMPLES_CNT1
= (
SIM_CAL_OPTION
==
"NONE"
) ?
12'hFFF
:
12'h001
;
133
localparam
[
11
:
0
]
NUM_SAMPLES_CNT2
= (
SIM_CAL_OPTION
==
"NONE"
) ?
12'hFFF
:
12'h001
;
134
135
136
wire
[
DQS_CNT_WIDTH
+
2
:
0
]
prbs_dqs_cnt_timing
;
137
reg
[
DQS_CNT_WIDTH
+
2
:
0
]
prbs_dqs_cnt_timing_r
;
138
reg
[
DQS_CNT_WIDTH
:
0
]
prbs_dqs_cnt_r
;
139
reg
prbs_prech_req_r
;
140
reg
[
5
:
0
]
prbs_state_r
;
141
reg
[
5
:
0
]
prbs_state_r1
;
142
reg
wait_state_cnt_en_r
;
143
reg
[
3
:
0
]
wait_state_cnt_r
;
144
reg
cnt_wait_state
;
145
reg
found_edge_r
;
146
reg
prbs_found_1st_edge_r
;
147
reg
prbs_found_2nd_edge_r
;
148
reg
[
5
:
0
]
prbs_1st_edge_taps_r
;
149
reg
found_stable_eye_r
;
150
reg
[
5
:
0
]
prbs_dqs_tap_cnt_r
;
151
reg
[
5
:
0
]
prbs_dec_tap_calc_plus_3
;
152
reg
[
5
:
0
]
prbs_dec_tap_calc_minus_3
;
153
reg
prbs_dqs_tap_limit_r
;
154
reg
[
5
:
0
]
prbs_inc_tap_cnt
;
155
reg
[
5
:
0
]
prbs_dec_tap_cnt
;
156
reg
[
DRAM_WIDTH
-
1
:
0
]
mux_rd_fall0_r1
;
157
reg
[
DRAM_WIDTH
-
1
:
0
]
mux_rd_fall1_r1
;
158
reg
[
DRAM_WIDTH
-
1
:
0
]
mux_rd_rise0_r1
;
159
reg
[
DRAM_WIDTH
-
1
:
0
]
mux_rd_rise1_r1
;
160
reg
[
DRAM_WIDTH
-
1
:
0
]
mux_rd_fall2_r1
;
161
reg
[
DRAM_WIDTH
-
1
:
0
]
mux_rd_fall3_r1
;
162
reg
[
DRAM_WIDTH
-
1
:
0
]
mux_rd_rise2_r1
;
163
reg
[
DRAM_WIDTH
-
1
:
0
]
mux_rd_rise3_r1
;
164
reg
[
DRAM_WIDTH
-
1
:
0
]
mux_rd_fall0_r2
;
165
reg
[
DRAM_WIDTH
-
1
:
0
]
mux_rd_fall1_r2
;
166
reg
[
DRAM_WIDTH
-
1
:
0
]
mux_rd_rise0_r2
;
167
reg
[
DRAM_WIDTH
-
1
:
0
]
mux_rd_rise1_r2
;
168
reg
[
DRAM_WIDTH
-
1
:
0
]
mux_rd_fall2_r2
;
169
reg
[
DRAM_WIDTH
-
1
:
0
]
mux_rd_fall3_r2
;
170
reg
[
DRAM_WIDTH
-
1
:
0
]
mux_rd_rise2_r2
;
171
reg
[
DRAM_WIDTH
-
1
:
0
]
mux_rd_rise3_r2
;
172
reg
mux_rd_valid_r
;
173
reg
rd_valid_r1
;
174
reg
rd_valid_r2
;
175
reg
rd_valid_r3
;
176
reg
new_cnt_dqs_r
;
177
reg
prbs_tap_en_r
;
178
reg
prbs_tap_inc_r
;
179
reg
pi_en_stg2_f_timing
;
180
reg
pi_stg2_f_incdec_timing
;
181
wire
[
DQ_WIDTH
-
1
:
0
]
rd_data_rise0
;
182
wire
[
DQ_WIDTH
-
1
:
0
]
rd_data_fall0
;
183
wire
[
DQ_WIDTH
-
1
:
0
]
rd_data_rise1
;
184
wire
[
DQ_WIDTH
-
1
:
0
]
rd_data_fall1
;
185
wire
[
DQ_WIDTH
-
1
:
0
]
rd_data_rise2
;
186
wire
[
DQ_WIDTH
-
1
:
0
]
rd_data_fall2
;
187
wire
[
DQ_WIDTH
-
1
:
0
]
rd_data_rise3
;
188
wire
[
DQ_WIDTH
-
1
:
0
]
rd_data_fall3
;
189
wire
[
PRBS_WIDTH
-
1
:
0
]
compare_data_r0
;
190
wire
[
PRBS_WIDTH
-
1
:
0
]
compare_data_f0
;
191
wire
[
PRBS_WIDTH
-
1
:
0
]
compare_data_r1
;
192
wire
[
PRBS_WIDTH
-
1
:
0
]
compare_data_f1
;
193
wire
[
PRBS_WIDTH
-
1
:
0
]
compare_data_r2
;
194
wire
[
PRBS_WIDTH
-
1
:
0
]
compare_data_f2
;
195
wire
[
PRBS_WIDTH
-
1
:
0
]
compare_data_r3
;
196
wire
[
PRBS_WIDTH
-
1
:
0
]
compare_data_f3
;
197
reg
[
DQS_CNT_WIDTH
:
0
]
rd_mux_sel_r
;
198
reg
[
5
:
0
]
prbs_2nd_edge_taps_r
;
199
200
reg
[
6
*
DQS_WIDTH
*
RANKS
-
1
:
0
]
prbs_final_dqs_tap_cnt_r
;
201
reg
[
1
:
0
]
rnk_cnt_r
;
202
reg
[
5
:
0
]
rdlvl_cpt_tap_cnt
;
203
reg
prbs_rdlvl_start_r
;
204
205
reg
compare_err
;
206
reg
compare_err_r0
;
207
reg
compare_err_f0
;
208
reg
compare_err_r1
;
209
reg
compare_err_f1
;
210
reg
compare_err_r2
;
211
reg
compare_err_f2
;
212
reg
compare_err_r3
;
213
reg
compare_err_f3
;
214
215
reg
samples_cnt1_en_r
;
216
reg
samples_cnt2_en_r
;
217
reg
[
11
:
0
]
samples_cnt_r
;
218
reg
num_samples_done_r
;
219
reg
[
DQS_WIDTH
-
1
:
0
]
prbs_tap_mod
;
220
221
222
223
224
//**************************************************************************
225
// DQS count to hard PHY during write calibration using Phaser_OUT Stage2
226
// coarse delay
227
//**************************************************************************
228
// assign pi_stg2_prbs_rdlvl_cnt = prbs_dqs_cnt_r;
229
// assign dbg_prbs_rdlvl = {prbs_tap_mod, prbs_2nd_edge_taps_r, prbs_1st_edge_taps_r, rdlvl_cpt_tap_cnt, prbs_dqs_cnt_r,
230
// prbs_rdlvl_done, prbs_rdlvl_start, phy_if_empty, compare_err, prbs_found_2nd_edge_r, prbs_found_1st_edge_r, prbs_dqs_tap_cnt_r, pi_counter_read_val,
231
// mux_rd_fall3_r2, mux_rd_rise3_r2, mux_rd_fall2_r2, mux_rd_rise2_r2, mux_rd_fall1_r2, mux_rd_rise1_r2, mux_rd_fall0_r2, mux_rd_rise0_r2,
232
// compare_data_f3, compare_data_r3, compare_data_f2, compare_data_r2, compare_data_f1, compare_data_r1, compare_data_f0, compare_data_r0};
233
234
assign
dbg_prbs_rdlvl
[
0
+:
8
] =
compare_data_r0
;
235
assign
dbg_prbs_rdlvl
[
8
+:
8
] =
compare_data_f0
;
236
assign
dbg_prbs_rdlvl
[
16
+:
8
] =
compare_data_r1
;
237
assign
dbg_prbs_rdlvl
[
24
+:
8
] =
compare_data_f1
;
238
assign
dbg_prbs_rdlvl
[
32
+:
8
] =
compare_data_r2
;
239
assign
dbg_prbs_rdlvl
[
40
+:
8
] =
compare_data_f2
;
240
assign
dbg_prbs_rdlvl
[
48
+:
8
] =
compare_data_r3
;
241
assign
dbg_prbs_rdlvl
[
56
+:
8
] =
compare_data_f3
;
242
243
assign
dbg_prbs_rdlvl
[
64
+:
8
] =
mux_rd_rise0_r2
;
244
assign
dbg_prbs_rdlvl
[
72
+:
8
] =
mux_rd_fall0_r2
;
245
assign
dbg_prbs_rdlvl
[
80
+:
8
] =
mux_rd_rise1_r2
;
246
assign
dbg_prbs_rdlvl
[
88
+:
8
] =
mux_rd_fall1_r2
;
247
assign
dbg_prbs_rdlvl
[
96
+:
8
] =
mux_rd_rise2_r2
;
248
assign
dbg_prbs_rdlvl
[
104
+:
8
] =
mux_rd_fall2_r2
;
249
assign
dbg_prbs_rdlvl
[
112
+:
8
] =
mux_rd_rise3_r2
;
250
assign
dbg_prbs_rdlvl
[
120
+:
8
] =
mux_rd_fall3_r2
;
251
252
assign
dbg_prbs_rdlvl
[
128
+:
6
] =
pi_counter_read_val
;
253
assign
dbg_prbs_rdlvl
[
134
+:
6
] =
prbs_dqs_tap_cnt_r
;
254
255
assign
dbg_prbs_rdlvl
[
140
] =
prbs_found_1st_edge_r
;
256
assign
dbg_prbs_rdlvl
[
141
] =
prbs_found_2nd_edge_r
;
257
assign
dbg_prbs_rdlvl
[
142
] =
compare_err
;
258
assign
dbg_prbs_rdlvl
[
143
] =
phy_if_empty
;
259
assign
dbg_prbs_rdlvl
[
144
] =
prbs_rdlvl_start
;
260
assign
dbg_prbs_rdlvl
[
145
] =
prbs_rdlvl_done
;
261
262
assign
dbg_prbs_rdlvl
[
146
+:
5
] =
prbs_dqs_cnt_r
;
263
assign
dbg_prbs_rdlvl
[
151
+:
6
] =
rdlvl_cpt_tap_cnt
;
264
assign
dbg_prbs_rdlvl
[
157
+:
6
] =
prbs_1st_edge_taps_r
;
265
assign
dbg_prbs_rdlvl
[
163
+:
6
] =
prbs_2nd_edge_taps_r
;
266
assign
dbg_prbs_rdlvl
[
169
+:
9
] =
prbs_tap_mod
;
267
268
assign
dbg_prbs_rdlvl
[
255
:
178
]=
'b0
;
//reserved
269
270
//***************************************************************************
271
//***************************************************************************
272
// Data mux to route appropriate bit to calibration logic - i.e. calibration
273
// is done sequentially, one bit (or DQS group) at a time
274
//***************************************************************************
275
276
generate
277
if
(
nCK_PER_CLK
==
4
)
begin
:
rd_data_div4_logic_clk
278
assign
rd_data_rise0
=
rd_data
[
DQ_WIDTH
-
1
:
0
];
279
assign
rd_data_fall0
=
rd_data
[
2
*
DQ_WIDTH
-
1
:
DQ_WIDTH
];
280
assign
rd_data_rise1
=
rd_data
[
3
*
DQ_WIDTH
-
1
:
2
*
DQ_WIDTH
];
281
assign
rd_data_fall1
=
rd_data
[
4
*
DQ_WIDTH
-
1
:
3
*
DQ_WIDTH
];
282
assign
rd_data_rise2
=
rd_data
[
5
*
DQ_WIDTH
-
1
:
4
*
DQ_WIDTH
];
283
assign
rd_data_fall2
=
rd_data
[
6
*
DQ_WIDTH
-
1
:
5
*
DQ_WIDTH
];
284
assign
rd_data_rise3
=
rd_data
[
7
*
DQ_WIDTH
-
1
:
6
*
DQ_WIDTH
];
285
assign
rd_data_fall3
=
rd_data
[
8
*
DQ_WIDTH
-
1
:
7
*
DQ_WIDTH
];
286
assign
compare_data_r0
=
compare_data
[
PRBS_WIDTH
-
1
:
0
];
287
assign
compare_data_f0
=
compare_data
[
2
*
PRBS_WIDTH
-
1
:
PRBS_WIDTH
];
288
assign
compare_data_r1
=
compare_data
[
3
*
PRBS_WIDTH
-
1
:
2
*
PRBS_WIDTH
];
289
assign
compare_data_f1
=
compare_data
[
4
*
PRBS_WIDTH
-
1
:
3
*
PRBS_WIDTH
];
290
assign
compare_data_r2
=
compare_data
[
5
*
PRBS_WIDTH
-
1
:
4
*
PRBS_WIDTH
];
291
assign
compare_data_f2
=
compare_data
[
6
*
PRBS_WIDTH
-
1
:
5
*
PRBS_WIDTH
];
292
assign
compare_data_r3
=
compare_data
[
7
*
PRBS_WIDTH
-
1
:
6
*
PRBS_WIDTH
];
293
assign
compare_data_f3
=
compare_data
[
8
*
PRBS_WIDTH
-
1
:
7
*
PRBS_WIDTH
];
294
end
else
begin
:
rd_data_div2_logic_clk
295
assign
rd_data_rise0
=
rd_data
[
DQ_WIDTH
-
1
:
0
];
296
assign
rd_data_fall0
=
rd_data
[
2
*
DQ_WIDTH
-
1
:
DQ_WIDTH
];
297
assign
rd_data_rise1
=
rd_data
[
3
*
DQ_WIDTH
-
1
:
2
*
DQ_WIDTH
];
298
assign
rd_data_fall1
=
rd_data
[
4
*
DQ_WIDTH
-
1
:
3
*
DQ_WIDTH
];
299
assign
compare_data_r0
=
compare_data
[
PRBS_WIDTH
-
1
:
0
];
300
assign
compare_data_f0
=
compare_data
[
2
*
PRBS_WIDTH
-
1
:
PRBS_WIDTH
];
301
assign
compare_data_r1
=
compare_data
[
3
*
PRBS_WIDTH
-
1
:
2
*
PRBS_WIDTH
];
302
assign
compare_data_f1
=
compare_data
[
4
*
PRBS_WIDTH
-
1
:
3
*
PRBS_WIDTH
];
303
end
304
endgenerate
305
306
always
@(
posedge
clk
)
begin
307
rd_mux_sel_r
<= #TCQ
prbs_dqs_cnt_r
;
308
end
309
310
// Register outputs for improved timing.
311
// NOTE: Will need to change when per-bit DQ deskew is supported.
312
// Currenly all bits in DQS group are checked in aggregate
313
generate
314
genvar
mux_i
;
315
for
(
mux_i
=
0
;
mux_i
<
DRAM_WIDTH
;
mux_i
=
mux_i
+
1
)
begin
:
gen_mux_rd
316
always
@(
posedge
clk
)
begin
317
mux_rd_rise0_r1
[
mux_i
] <= #TCQ
rd_data_rise0
[
DRAM_WIDTH
*
rd_mux_sel_r
+
mux_i
];
318
mux_rd_fall0_r1
[
mux_i
] <= #TCQ
rd_data_fall0
[
DRAM_WIDTH
*
rd_mux_sel_r
+
mux_i
];
319
mux_rd_rise1_r1
[
mux_i
] <= #TCQ
rd_data_rise1
[
DRAM_WIDTH
*
rd_mux_sel_r
+
mux_i
];
320
mux_rd_fall1_r1
[
mux_i
] <= #TCQ
rd_data_fall1
[
DRAM_WIDTH
*
rd_mux_sel_r
+
mux_i
];
321
mux_rd_rise2_r1
[
mux_i
] <= #TCQ
rd_data_rise2
[
DRAM_WIDTH
*
rd_mux_sel_r
+
mux_i
];
322
mux_rd_fall2_r1
[
mux_i
] <= #TCQ
rd_data_fall2
[
DRAM_WIDTH
*
rd_mux_sel_r
+
mux_i
];
323
mux_rd_rise3_r1
[
mux_i
] <= #TCQ
rd_data_rise3
[
DRAM_WIDTH
*
rd_mux_sel_r
+
mux_i
];
324
mux_rd_fall3_r1
[
mux_i
] <= #TCQ
rd_data_fall3
[
DRAM_WIDTH
*
rd_mux_sel_r
+
mux_i
];
325
end
326
end
327
endgenerate
328
329
generate
330
genvar
muxr2_i
;
331
if
(
nCK_PER_CLK
==
4
)
begin
:
gen_mux_div4
332
for
(
muxr2_i
=
0
;
muxr2_i
<
DRAM_WIDTH
;
muxr2_i
=
muxr2_i
+
1
)
begin
:
gen_rd_4
333
always
@(
posedge
clk
)
begin
334
if
(
mux_rd_valid_r
)
begin
335
mux_rd_rise0_r2
[
muxr2_i
] <= #TCQ
mux_rd_rise0_r1
[
muxr2_i
];
336
mux_rd_fall0_r2
[
muxr2_i
] <= #TCQ
mux_rd_fall0_r1
[
muxr2_i
];
337
mux_rd_rise1_r2
[
muxr2_i
] <= #TCQ
mux_rd_rise1_r1
[
muxr2_i
];
338
mux_rd_fall1_r2
[
muxr2_i
] <= #TCQ
mux_rd_fall1_r1
[
muxr2_i
];
339
mux_rd_rise2_r2
[
muxr2_i
] <= #TCQ
mux_rd_rise2_r1
[
muxr2_i
];
340
mux_rd_fall2_r2
[
muxr2_i
] <= #TCQ
mux_rd_fall2_r1
[
muxr2_i
];
341
mux_rd_rise3_r2
[
muxr2_i
] <= #TCQ
mux_rd_rise3_r1
[
muxr2_i
];
342
mux_rd_fall3_r2
[
muxr2_i
] <= #TCQ
mux_rd_fall3_r1
[
muxr2_i
];
343
end
344
end
345
end
346
end
else
if
(
nCK_PER_CLK
==
2
)
begin
:
gen_mux_div2
347
for
(
muxr2_i
=
0
;
muxr2_i
<
DRAM_WIDTH
;
muxr2_i
=
muxr2_i
+
1
)
begin
:
gen_rd_2
348
always
@(
posedge
clk
)
begin
349
if
(
mux_rd_valid_r
)
begin
350
mux_rd_rise0_r2
[
muxr2_i
] <= #TCQ
mux_rd_rise0_r1
[
muxr2_i
];
351
mux_rd_fall0_r2
[
muxr2_i
] <= #TCQ
mux_rd_fall0_r1
[
muxr2_i
];
352
mux_rd_rise1_r2
[
muxr2_i
] <= #TCQ
mux_rd_rise1_r1
[
muxr2_i
];
353
mux_rd_fall1_r2
[
muxr2_i
] <= #TCQ
mux_rd_fall1_r1
[
muxr2_i
];
354
end
355
end
356
end
357
end
358
endgenerate
359
360
361
// Registered signal indicates when mux_rd_rise/fall_r is valid
362
always
@(
posedge
clk
)
begin
363
mux_rd_valid_r
<= #TCQ ~
phy_if_empty
&&
prbs_rdlvl_start
;
364
rd_valid_r1
<= #TCQ
mux_rd_valid_r
;
365
rd_valid_r2
<= #TCQ
rd_valid_r1
;
366
end
367
368
// Counter counts # of samples compared
369
// Reset sample counter when not "sampling"
370
// Otherwise, count # of samples compared
371
// Same counter is shared for three samples checked
372
always
@(
posedge
clk
)
373
if
(
rst
)
374
samples_cnt_r
<= #TCQ
'b0
;
375
else
begin
376
if
(!
rd_valid_r1
||
377
(
prbs_state_r
==
PRBS_DEC_DQS_WAIT
) ||
378
(
prbs_state_r
==
PRBS_INC_DQS_WAIT
) ||
379
(
prbs_state_r
==
PRBS_DEC_DQS
) ||
380
(
prbs_state_r
==
PRBS_INC_DQS
) ||
381
(
samples_cnt_r
==
NUM_SAMPLES_CNT
) ||
382
(
samples_cnt_r
==
NUM_SAMPLES_CNT1
))
383
samples_cnt_r
<= #TCQ
'b0
;
384
else
if
(
rd_valid_r1
&&
385
(((
samples_cnt_r
<
NUM_SAMPLES_CNT
) && ~
samples_cnt1_en_r
) ||
386
((
samples_cnt_r
<
NUM_SAMPLES_CNT1
) && ~
samples_cnt2_en_r
) ||
387
((
samples_cnt_r
<
NUM_SAMPLES_CNT2
) &&
samples_cnt2_en_r
)))
388
samples_cnt_r
<= #TCQ
samples_cnt_r
+
1
;
389
end
390
391
// Count #2 enable generation
392
// Assert when correct number of samples compared
393
always
@(
posedge
clk
)
394
if
(
rst
)
395
samples_cnt1_en_r
<= #TCQ
1'b0
;
396
else
begin
397
if
((
prbs_state_r
==
PRBS_IDLE
) ||
398
(
prbs_state_r
==
PRBS_DEC_DQS
) ||
399
(
prbs_state_r
==
PRBS_INC_DQS
) ||
400
(
prbs_state_r
==
PRBS_NEW_DQS_PREWAIT
))
401
samples_cnt1_en_r
<= #TCQ
1'b0
;
402
else
if
((
samples_cnt_r
==
NUM_SAMPLES_CNT
) &&
rd_valid_r1
)
403
samples_cnt1_en_r
<= #TCQ
1'b1
;
404
end
405
406
// Counter #3 enable generation
407
// Assert when correct number of samples compared
408
always
@(
posedge
clk
)
409
if
(
rst
)
410
samples_cnt2_en_r
<= #TCQ
1'b0
;
411
else
begin
412
if
((
prbs_state_r
==
PRBS_IDLE
) ||
413
(
prbs_state_r
==
PRBS_DEC_DQS
) ||
414
(
prbs_state_r
==
PRBS_INC_DQS
) ||
415
(
prbs_state_r
==
PRBS_NEW_DQS_PREWAIT
))
416
samples_cnt2_en_r
<= #TCQ
1'b0
;
417
else
if
((
samples_cnt_r
==
NUM_SAMPLES_CNT1
) &&
rd_valid_r1
&&
samples_cnt1_en_r
)
418
samples_cnt2_en_r
<= #TCQ
1'b1
;
419
end
420
421
// Assert when all the three sample counts are done
422
always
@(
posedge
clk
)
423
if
(
rst
)
424
num_samples_done_r
<= #TCQ
1'b0
;
425
else
begin
426
if
(!
rd_valid_r1
||
427
(
prbs_state_r
==
PRBS_DEC_DQS
) ||
428
(
prbs_state_r
==
PRBS_INC_DQS
))
429
num_samples_done_r
<= #TCQ
'b0
;
430
else
begin
431
if
((
samples_cnt_r
==
NUM_SAMPLES_CNT2
-
1
) &&
samples_cnt2_en_r
)
432
num_samples_done_r
<= #TCQ
1'b1
;
433
end
434
end
435
436
437
//***************************************************************************
438
// Compare Read Data for the byte being Leveled with Expected data from PRBS
439
// generator. Resulting compare_err signal used to determine read data valid
440
// edge.
441
//***************************************************************************
442
generate
443
if
(
nCK_PER_CLK
==
4
)
begin
:
cmp_err_4to1
444
always
@ (
posedge
clk
)
begin
445
if
(
rst
||
new_cnt_dqs_r
)
begin
446
compare_err
<= #TCQ
1'b0
;
447
compare_err_r0
<= #TCQ
1'b0
;
448
compare_err_f0
<= #TCQ
1'b0
;
449
compare_err_r1
<= #TCQ
1'b0
;
450
compare_err_f1
<= #TCQ
1'b0
;
451
compare_err_r2
<= #TCQ
1'b0
;
452
compare_err_f2
<= #TCQ
1'b0
;
453
compare_err_r3
<= #TCQ
1'b0
;
454
compare_err_f3
<= #TCQ
1'b0
;
455
end
else
if
(
rd_valid_r1
)
begin
456
compare_err_r0
<= #TCQ (
mux_rd_rise0_r2
!=
compare_data_r0
);
457
compare_err_f0
<= #TCQ (
mux_rd_fall0_r2
!=
compare_data_f0
);
458
compare_err_r1
<= #TCQ (
mux_rd_rise1_r2
!=
compare_data_r1
);
459
compare_err_f1
<= #TCQ (
mux_rd_fall1_r2
!=
compare_data_f1
);
460
compare_err_r2
<= #TCQ (
mux_rd_rise2_r2
!=
compare_data_r2
);
461
compare_err_f2
<= #TCQ (
mux_rd_fall2_r2
!=
compare_data_f2
);
462
compare_err_r3
<= #TCQ (
mux_rd_rise3_r2
!=
compare_data_r3
);
463
compare_err_f3
<= #TCQ (
mux_rd_fall3_r2
!=
compare_data_f3
);
464
compare_err
<= #TCQ (
compare_err_r0
|
compare_err_f0
|
465
compare_err_r1
|
compare_err_f1
|
466
compare_err_r2
|
compare_err_f2
|
467
compare_err_r3
|
compare_err_f3
);
468
end
469
end
470
end
else
begin
:
cmp_err_2to1
471
always
@ (
posedge
clk
)
begin
472
if
(
rst
||
new_cnt_dqs_r
)
begin
473
compare_err
<= #TCQ
1'b0
;
474
compare_err_r0
<= #TCQ
1'b0
;
475
compare_err_f0
<= #TCQ
1'b0
;
476
compare_err_r1
<= #TCQ
1'b0
;
477
compare_err_f1
<= #TCQ
1'b0
;
478
end
else
if
(
rd_valid_r1
)
begin
479
compare_err_r0
<= #TCQ (
mux_rd_rise0_r2
!=
compare_data_r0
);
480
compare_err_f0
<= #TCQ (
mux_rd_fall0_r2
!=
compare_data_f0
);
481
compare_err_r1
<= #TCQ (
mux_rd_rise1_r2
!=
compare_data_r1
);
482
compare_err_f1
<= #TCQ (
mux_rd_fall1_r2
!=
compare_data_f1
);
483
compare_err
<= #TCQ (
compare_err_r0
|
compare_err_f0
|
484
compare_err_r1
|
compare_err_f1
);
485
end
486
end
487
end
488
endgenerate
489
490
//***************************************************************************
491
// Decrement initial Phaser_IN fine delay value before proceeding with
492
// read calibration
493
//***************************************************************************
494
495
496
//***************************************************************************
497
// Demultiplexor to control Phaser_IN delay values
498
//***************************************************************************
499
500
// Read DQS
501
always
@(
posedge
clk
)
begin
502
if
(
rst
)
begin
503
pi_en_stg2_f_timing
<= #TCQ
'b0
;
504
pi_stg2_f_incdec_timing
<= #TCQ
'b0
;
505
end
else
if
(
prbs_tap_en_r
)
begin
506
// Change only specified DQS
507
pi_en_stg2_f_timing
<= #TCQ
1'b1
;
508
pi_stg2_f_incdec_timing
<= #TCQ
prbs_tap_inc_r
;
509
end
else
begin
510
pi_en_stg2_f_timing
<= #TCQ
'b0
;
511
pi_stg2_f_incdec_timing
<= #TCQ
'b0
;
512
end
513
end
514
515
// registered for timing
516
always
@(
posedge
clk
)
begin
517
pi_en_stg2_f
<= #TCQ
pi_en_stg2_f_timing
;
518
pi_stg2_f_incdec
<= #TCQ
pi_stg2_f_incdec_timing
;
519
end
520
521
//***************************************************************************
522
// generate request to PHY_INIT logic to issue precharged. Required when
523
// calibration can take a long time (during which there are only constant
524
// reads present on this bus). In this case need to issue perioidic
525
// precharges to avoid tRAS violation. This signal must meet the following
526
// requirements: (1) only transition from 0->1 when prech is first needed,
527
// (2) stay at 1 and only transition 1->0 when RDLVL_PRECH_DONE asserted
528
//***************************************************************************
529
530
always
@(
posedge
clk
)
531
if
(
rst
)
532
prbs_rdlvl_prech_req
<= #TCQ
1'b0
;
533
else
534
prbs_rdlvl_prech_req
<= #TCQ
prbs_prech_req_r
;
535
536
//*****************************************************************
537
// keep track of edge tap counts found, and current capture clock
538
// tap count
539
//*****************************************************************
540
541
always
@(
posedge
clk
)
542
if
(
rst
)
begin
543
prbs_dqs_tap_cnt_r
<= #TCQ
'b0
;
544
rdlvl_cpt_tap_cnt
<= #TCQ
'b0
;
545
end
else
if
(
new_cnt_dqs_r
)
begin
546
prbs_dqs_tap_cnt_r
<= #TCQ
pi_counter_read_val
;
547
rdlvl_cpt_tap_cnt
<= #TCQ
pi_counter_read_val
;
548
end
else
if
(
prbs_tap_en_r
)
begin
549
if
(
prbs_tap_inc_r
)
550
prbs_dqs_tap_cnt_r
<= #TCQ
prbs_dqs_tap_cnt_r
+
1
;
551
else
if
(
prbs_dqs_tap_cnt_r
!=
'd0
)
552
prbs_dqs_tap_cnt_r
<= #TCQ
prbs_dqs_tap_cnt_r
-
1
;
553
end
554
555
always
@(
posedge
clk
)
556
if
(
rst
)
begin
557
prbs_dec_tap_calc_plus_3
<= #TCQ
'b0
;
558
prbs_dec_tap_calc_minus_3
<= #TCQ
'b0
;
559
end
else
if
(
new_cnt_dqs_r
)
begin
560
prbs_dec_tap_calc_plus_3
<= #TCQ
'b000011
;
561
prbs_dec_tap_calc_minus_3
<= #TCQ
'b111100
;
562
end
else
begin
563
prbs_dec_tap_calc_plus_3
<= #TCQ (
prbs_dqs_tap_cnt_r
-
rdlvl_cpt_tap_cnt
+
3
);
564
prbs_dec_tap_calc_minus_3
<= #TCQ (
prbs_dqs_tap_cnt_r
-
rdlvl_cpt_tap_cnt
-
3
);
565
end
566
567
always
@(
posedge
clk
)
568
if
(
rst
||
new_cnt_dqs_r
)
569
prbs_dqs_tap_limit_r
<= #TCQ
1'b0
;
570
else
if
(
prbs_dqs_tap_cnt_r
==
6'd63
)
571
prbs_dqs_tap_limit_r
<= #TCQ
1'b1
;
572
573
// Temp wire for timing.
574
// The following in the always block below causes timing issues
575
// due to DSP block inference
576
// 6*prbs_dqs_cnt_r.
577
// replacing this with two left shifts + one left shift to avoid
578
// DSP multiplier.
579
580
assign
prbs_dqs_cnt_timing
= {
2'd0
,
prbs_dqs_cnt_r
};
581
582
583
always
@(
posedge
clk
)
584
prbs_dqs_cnt_timing_r
<= #TCQ
prbs_dqs_cnt_timing
;
585
586
587
// Storing DQS tap values at the end of each DQS read leveling
588
always
@(
posedge
clk
)
begin
589
if
(
rst
)
begin
590
prbs_final_dqs_tap_cnt_r
<= #TCQ
'b0
;
591
end
else
if
((
prbs_state_r
==
PRBS_NEXT_DQS
) && (
prbs_state_r1
!=
PRBS_NEXT_DQS
))
begin
592
prbs_final_dqs_tap_cnt_r
[(((
prbs_dqs_cnt_timing_r
<<
2
) + (
prbs_dqs_cnt_timing_r
<<
1
))
593
+(
rnk_cnt_r
*
DQS_WIDTH
*
6
))+:
6
]
594
<= #TCQ
prbs_dqs_tap_cnt_r
;
595
end
596
end
597
598
599
600
601
//*****************************************************************
602
603
always
@(
posedge
clk
)
begin
604
prbs_state_r1
<= #TCQ
prbs_state_r
;
605
prbs_rdlvl_start_r
<= #TCQ
prbs_rdlvl_start
;
606
end
607
608
// Wait counter for wait states
609
always
@(
posedge
clk
)
610
if
((
prbs_state_r
==
PRBS_NEW_DQS_WAIT
) ||
611
(
prbs_state_r
==
PRBS_INC_DQS_WAIT
) ||
612
(
prbs_state_r
==
PRBS_DEC_DQS_WAIT
) ||
613
(
prbs_state_r
==
PRBS_NEW_DQS_PREWAIT
))
614
wait_state_cnt_en_r
<= #TCQ
1'b1
;
615
else
616
wait_state_cnt_en_r
<= #TCQ
1'b0
;
617
618
always
@(
posedge
clk
)
619
if
(!
wait_state_cnt_en_r
)
begin
620
wait_state_cnt_r
<= #TCQ
'b0
;
621
cnt_wait_state
<= #TCQ
1'b0
;
622
end
else
begin
623
if
(
wait_state_cnt_r
<
'd15
)
begin
624
wait_state_cnt_r
<= #TCQ
wait_state_cnt_r
+
1
;
625
cnt_wait_state
<= #TCQ
1'b0
;
626
end
else
begin
627
// Need to reset to 0 to handle the case when there are two
628
// different WAIT states back-to-back
629
wait_state_cnt_r
<= #TCQ
'b0
;
630
cnt_wait_state
<= #TCQ
1'b1
;
631
end
632
end
633
634
//*****************************************************************
635
// PRBS Read Level State Machine
636
//*****************************************************************
637
638
always
@(
posedge
clk
)
639
if
(
rst
)
begin
640
prbs_dqs_cnt_r
<= #TCQ
'b0
;
641
prbs_tap_en_r
<= #TCQ
1'b0
;
642
prbs_tap_inc_r
<= #TCQ
1'b0
;
643
prbs_prech_req_r
<= #TCQ
1'b0
;
644
prbs_state_r
<= #TCQ
PRBS_IDLE
;
645
prbs_found_1st_edge_r
<= #TCQ
1'b0
;
646
prbs_found_2nd_edge_r
<= #TCQ
1'b0
;
647
prbs_1st_edge_taps_r
<= #TCQ
6'bxxxxxx
;
648
prbs_inc_tap_cnt
<= #TCQ
'b0
;
649
prbs_dec_tap_cnt
<= #TCQ
'b0
;
650
new_cnt_dqs_r
<= #TCQ
1'b0
;
651
if
(
SIM_CAL_OPTION
==
"FAST_CAL"
)
652
prbs_rdlvl_done
<= #TCQ
1'b1
;
653
else
654
prbs_rdlvl_done
<= #TCQ
1'b0
;
655
prbs_2nd_edge_taps_r
<= #TCQ
6'bxxxxxx
;
656
prbs_last_byte_done
<= #TCQ
1'b0
;
657
rnk_cnt_r
<= #TCQ
2'b00
;
658
prbs_tap_mod
<= #TCQ
'd0
;
659
end
else
begin
660
661
case
(
prbs_state_r
)
662
663
PRBS_IDLE
:
begin
664
prbs_last_byte_done
<= #TCQ
1'b0
;
665
prbs_prech_req_r
<= #TCQ
1'b0
;
666
if
(
prbs_rdlvl_start
&& ~
prbs_rdlvl_start_r
)
begin
667
if
(
SIM_CAL_OPTION
==
"SKIP_CAL"
)
668
prbs_state_r
<= #TCQ
PRBS_DONE
;
669
else
begin
670
new_cnt_dqs_r
<= #TCQ
1'b1
;
671
prbs_state_r
<= #TCQ
PRBS_NEW_DQS_WAIT
;
672
end
673
end
674
end
675
676
// Wait for the new DQS group to change
677
// also gives time for the read data IN_FIFO to
678
// output the updated data for the new DQS group
679
PRBS_NEW_DQS_WAIT
:
begin
680
prbs_last_byte_done
<= #TCQ
1'b0
;
681
prbs_prech_req_r
<= #TCQ
1'b0
;
682
if
(
cnt_wait_state
)
begin
683
new_cnt_dqs_r
<= #TCQ
1'b0
;
684
prbs_state_r
<= #TCQ
PRBS_PAT_COMPARE
;
685
end
686
end
687
688
// Check for presence of data eye edge. During this state, we
689
// sample the read data multiple times, and look for changes
690
// in the read data, specifically:
691
// 1. A change in the read data compared with the value of
692
// read data from the previous delay tap. This indicates
693
// that the most recent tap delay increment has moved us
694
// into either a new window, or moved/kept us in the
695
// transition/jitter region between windows. Note that this
696
// condition only needs to be checked for once, and for
697
// logistical purposes, we check this soon after entering
698
// this state (see comment in PRBS_PAT_COMPARE below for
699
// why this is done)
700
// 2. A change in the read data while we are in this state
701
// (i.e. in the absence of a tap delay increment). This
702
// indicates that we're close enough to a window edge that
703
// jitter will cause the read data to change even in the
704
// absence of a tap delay change
705
PRBS_PAT_COMPARE
:
begin
706
707
// Continue to sample read data and look for edges until the
708
// appropriate time interval (shorter for simulation-only,
709
// much, much longer for actual h/w) has elapsed
710
if
(
num_samples_done_r
||
compare_err
)
begin
711
if
(
prbs_dqs_tap_limit_r
)
712
// Only one edge detected and ran out of taps since only one
713
// bit time worth of taps available for window detection. This
714
// can happen if at tap 0 DQS is in previous window which results
715
// in only left edge being detected. Or at tap 0 DQS is in the
716
// current window resulting in only right edge being detected.
717
// Depending on the frequency this case can also happen if at
718
// tap 0 DQS is in the left noise region resulting in only left
719
// edge being detected.
720
prbs_state_r
<= #TCQ
PRBS_CALC_TAPS
;
721
else
if
(
compare_err
|| (
prbs_dqs_tap_cnt_r
==
'd0
))
begin
722
// Sticky bit - asserted after we encounter an edge, although
723
// the current edge may not be considered the "first edge" this
724
// just means we found at least one edge
725
prbs_found_1st_edge_r
<= #TCQ
1'b1
;
726
727
// Both edges of data valid window found:
728
// If we've found a second edge after a region of stability
729
// then we must have just passed the second ("right" edge of
730
// the window. Record this second_edge_taps = current tap-1,
731
// because we're one past the actual second edge tap, where
732
// the edge taps represent the extremes of the data valid
733
// window (i.e. smallest & largest taps where data still valid
734
if
(
prbs_found_1st_edge_r
)
begin
735
prbs_found_2nd_edge_r
<= #TCQ
1'b1
;
736
prbs_2nd_edge_taps_r
<= #TCQ
prbs_dqs_tap_cnt_r
-
1
;
737
prbs_state_r
<= #TCQ
PRBS_CALC_TAPS
;
738
end
else
begin
739
// Otherwise, an edge was found (just not the "second" edge)
740
// Assuming DQS is in the correct window at tap 0 of Phaser IN
741
// fine tap. The first edge found is the right edge of the valid
742
// window and is the beginning of the jitter region hence done!
743
if
(
compare_err
)
744
prbs_1st_edge_taps_r
<= #TCQ
prbs_dqs_tap_cnt_r
+
1
;
745
else
746
prbs_1st_edge_taps_r
<= #TCQ
'd0
;
747
748
prbs_inc_tap_cnt
<= #TCQ
rdlvl_cpt_tap_cnt
-
prbs_dqs_tap_cnt_r
;
749
prbs_state_r
<= #TCQ
PRBS_INC_DQS
;
750
end
751
end
else
begin
752
// Otherwise, if we haven't found an edge....
753
// If we still have taps left to use, then keep incrementing
754
if
(
prbs_found_1st_edge_r
)
755
prbs_state_r
<= #TCQ
PRBS_INC_DQS
;
756
else
757
prbs_state_r
<= #TCQ
PRBS_DEC_DQS
;
758
end
759
end
760
end
761
762
// Increment Phaser_IN delay for DQS
763
PRBS_INC_DQS
:
begin
764
prbs_state_r
<= #TCQ
PRBS_INC_DQS_WAIT
;
765
if
(
prbs_inc_tap_cnt
>
'd0
)
766
prbs_inc_tap_cnt
<= #TCQ
prbs_inc_tap_cnt
-
1
;
767
if
(~
prbs_dqs_tap_limit_r
)
begin
768
prbs_tap_en_r
<= #TCQ
1'b1
;
769
prbs_tap_inc_r
<= #TCQ
1'b1
;
770
end
else
begin
771
prbs_tap_en_r
<= #TCQ
1'b0
;
772
prbs_tap_inc_r
<= #TCQ
1'b0
;
773
end
774
end
775
776
// Wait for Phaser_In to settle, before checking again for an edge
777
PRBS_INC_DQS_WAIT
:
begin
778
prbs_tap_en_r
<= #TCQ
1'b0
;
779
prbs_tap_inc_r
<= #TCQ
1'b0
;
780
if
(
cnt_wait_state
)
begin
781
if
(
prbs_inc_tap_cnt
>
'd0
)
782
prbs_state_r
<= #TCQ
PRBS_INC_DQS
;
783
else
784
prbs_state_r
<= #TCQ
PRBS_PAT_COMPARE
;
785
end
786
end
787
788
// Calculate final value of Phaser_IN taps. At this point, one or both
789
// edges of data eye have been found, and/or all taps have been
790
// exhausted looking for the edges
791
// NOTE: The amount to be decrement by is calculated, not the
792
// absolute setting for DQS.
793
PRBS_CALC_TAPS
:
begin
794
if
(
prbs_found_2nd_edge_r
&&
prbs_found_1st_edge_r
)
795
// Both edges detected
796
prbs_dec_tap_cnt
797
<= #TCQ ((
prbs_2nd_edge_taps_r
-
798
prbs_1st_edge_taps_r
)>>
1
) +
1
;
799
else
if
(~
prbs_found_2nd_edge_r
&&
prbs_found_1st_edge_r
)
800
// Only left edge detected
801
prbs_dec_tap_cnt
802
<= #TCQ ((
prbs_dqs_tap_cnt_r
-
prbs_1st_edge_taps_r
)>>
1
);
803
else
804
// No edges detected
805
prbs_dec_tap_cnt
806
<= #TCQ (
prbs_dqs_tap_cnt_r
>>
1
);
807
// Now use the value we just calculated to decrement CPT taps
808
// to the desired calibration point
809
prbs_state_r
<= #TCQ
PRBS_TAP_CHECK
;
//PRBS_DEC_DQS;
810
end
811
812
PRBS_TAP_CHECK
:
begin
813
// Fix for CR690798 - limit PRBS tap to +/- 3 taps of rdlvl_cpt_tap_cnt
814
if
(
prbs_dec_tap_calc_minus_3
>
prbs_dec_tap_cnt
)
begin
// proposing a re-order of the condition
815
prbs_tap_mod
[
prbs_dqs_cnt_timing_r
] <= #TCQ
1'b1
;
816
prbs_dec_tap_cnt
<= #TCQ
prbs_dec_tap_calc_minus_3
;
817
end
else
if
(
prbs_dec_tap_calc_plus_3
<
prbs_dec_tap_cnt
)
begin
// proposing a re-order of the condition
818
prbs_tap_mod
[
prbs_dqs_cnt_timing_r
] <= #TCQ
1'b1
;
819
prbs_dec_tap_cnt
<= #TCQ
prbs_dec_tap_calc_plus_3
;
820
end
821
prbs_state_r
<= #TCQ
PRBS_DEC_DQS
;
822
end
823
824
// decrement capture clock for final adjustment - center
825
// capture clock in middle of data eye. This adjustment will occur
826
// only when both the edges are found usign CPT taps. Must do this
827
// incrementally to avoid clock glitching (since CPT drives clock
828
// divider within each ISERDES)
829
PRBS_DEC_DQS
:
begin
830
prbs_tap_en_r
<= #TCQ
1'b1
;
831
prbs_tap_inc_r
<= #TCQ
1'b0
;
832
// once adjustment is complete, we're done with calibration for
833
// this DQS, repeat for next DQS
834
if
(
prbs_dec_tap_cnt
>
'd0
)
835
prbs_dec_tap_cnt
<= #TCQ
prbs_dec_tap_cnt
-
1
;
836
if
(
prbs_dec_tap_cnt
==
6'b000001
)
837
prbs_state_r
<= #TCQ
PRBS_NEXT_DQS
;
838
else
839
prbs_state_r
<= #TCQ
PRBS_DEC_DQS_WAIT
;
840
end
841
842
PRBS_DEC_DQS_WAIT
:
begin
843
prbs_tap_en_r
<= #TCQ
1'b0
;
844
prbs_tap_inc_r
<= #TCQ
1'b0
;
845
if
(
cnt_wait_state
)
begin
846
if
(
prbs_dec_tap_cnt
>
'd0
)
847
prbs_state_r
<= #TCQ
PRBS_DEC_DQS
;
848
else
849
prbs_state_r
<= #TCQ
PRBS_PAT_COMPARE
;
850
end
851
end
852
853
// Determine whether we're done, or have more DQS's to calibrate
854
// Also request precharge after every byte, as appropriate
855
PRBS_NEXT_DQS
:
begin
856
prbs_prech_req_r
<= #TCQ
1'b1
;
857
prbs_tap_en_r
<= #TCQ
1'b0
;
858
prbs_tap_inc_r
<= #TCQ
1'b0
;
859
// Prepare for another iteration with next DQS group
860
prbs_found_1st_edge_r
<= #TCQ
1'b0
;
861
prbs_found_2nd_edge_r
<= #TCQ
1'b0
;
862
prbs_1st_edge_taps_r
<= #TCQ
'd0
;
863
prbs_2nd_edge_taps_r
<= #TCQ
'd0
;
864
if
(
prbs_dqs_cnt_r
>=
DQS_WIDTH
-
1
)
begin
865
prbs_last_byte_done
<= #TCQ
1'b1
;
866
end
867
868
// Wait until precharge that occurs in between calibration of
869
// DQS groups is finished
870
if
(
prech_done
)
begin
871
prbs_prech_req_r
<= #TCQ
1'b0
;
872
if
(
prbs_dqs_cnt_r
>=
DQS_WIDTH
-
1
)
begin
873
if
(
rnk_cnt_r
==
RANKS
-
1
)
begin
874
// All DQS groups in all ranks done
875
prbs_state_r
<= #TCQ
PRBS_DONE
;
876
end
else
begin
877
// Process DQS groups in next rank
878
rnk_cnt_r
<= #TCQ
rnk_cnt_r
+
1
;
879
new_cnt_dqs_r
<= #TCQ
1'b1
;
880
prbs_dqs_cnt_r
<= #TCQ
'b0
;
881
prbs_state_r
<= #TCQ
PRBS_IDLE
;
882
end
883
end
else
begin
884
// Process next DQS group
885
new_cnt_dqs_r
<= #TCQ
1'b1
;
886
prbs_dqs_cnt_r
<= #TCQ
prbs_dqs_cnt_r
+
1
;
887
prbs_state_r
<= #TCQ
PRBS_NEW_DQS_PREWAIT
;
888
end
889
end
890
end
891
892
PRBS_NEW_DQS_PREWAIT
:
begin
893
if
(
cnt_wait_state
)
begin
894
prbs_state_r
<= #TCQ
PRBS_NEW_DQS_WAIT
;
895
end
896
end
897
898
// Done with this stage of calibration
899
PRBS_DONE
:
begin
900
prbs_prech_req_r
<= #TCQ
1'b0
;
901
prbs_last_byte_done
<= #TCQ
1'b0
;
902
prbs_rdlvl_done
<= #TCQ
1'b1
;
903
end
904
905
endcase
906
end
907
908
endmodule
Generated on Sun Mar 6 2016 12:24:20 for AMC13 by
1.8.1