1 | //***************************************************************************** |
---|
2 | // DISCLAIMER OF LIABILITY |
---|
3 | // |
---|
4 | // This file contains proprietary and confidential information of |
---|
5 | // Xilinx, Inc. ("Xilinx"), that is distributed under a license |
---|
6 | // from Xilinx, and may be used, copied and/or disclosed only |
---|
7 | // pursuant to the terms of a valid license agreement with Xilinx. |
---|
8 | // |
---|
9 | // XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION |
---|
10 | // ("MATERIALS") "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER |
---|
11 | // EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING WITHOUT |
---|
12 | // LIMITATION, ANY WARRANTY WITH RESPECT TO NONINFRINGEMENT, |
---|
13 | // MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. Xilinx |
---|
14 | // does not warrant that functions included in the Materials will |
---|
15 | // meet the requirements of Licensee, or that the operation of the |
---|
16 | // Materials will be uninterrupted or error-free, or that defects |
---|
17 | // in the Materials will be corrected. Furthermore, Xilinx does |
---|
18 | // not warrant or make any representations regarding use, or the |
---|
19 | // results of the use, of the Materials in terms of correctness, |
---|
20 | // accuracy, reliability or otherwise. |
---|
21 | // |
---|
22 | // Xilinx products are not designed or intended to be fail-safe, |
---|
23 | // or for use in any application requiring fail-safe performance, |
---|
24 | // such as life-support or safety devices or systems, Class III |
---|
25 | // medical devices, nuclear facilities, applications related to |
---|
26 | // the deployment of airbags, or any other applications that could |
---|
27 | // lead to death, personal injury or severe property or |
---|
28 | // environmental damage (individually and collectively, "critical |
---|
29 | // applications"). Customer assumes the sole risk and liability |
---|
30 | // of any use of Xilinx products in critical applications, |
---|
31 | // subject only to applicable laws and regulations governing |
---|
32 | // limitations on product liability. |
---|
33 | // |
---|
34 | // Copyright 2006, 2007, 2008 Xilinx, Inc. |
---|
35 | // All rights reserved. |
---|
36 | // |
---|
37 | // This disclaimer and copyright notice must be retained as part |
---|
38 | // of this file at all times. |
---|
39 | //***************************************************************************** |
---|
40 | // ____ ____ |
---|
41 | // / /\/ / |
---|
42 | // /___/ \ / Vendor: Xilinx |
---|
43 | // \ \ \/ Version: 3.6 |
---|
44 | // \ \ Application: MIG |
---|
45 | // / / Filename: ddr2_phy_init.v |
---|
46 | // /___/ /\ Date Last Modified: $Date: 2010/06/29 12:03:43 $ |
---|
47 | // \ \ / \ Date Created: Thu Aug 24 2006 |
---|
48 | // \___\/\___\ |
---|
49 | // |
---|
50 | //Device: Virtex-5 |
---|
51 | //Design Name: DDR2 |
---|
52 | //Purpose: |
---|
53 | //Reference: |
---|
54 | // This module is the intialization control logic of the memory interface. |
---|
55 | // All commands are issued from here acoording to the burst, CAS Latency and |
---|
56 | // the user commands. |
---|
57 | //Revision History: |
---|
58 | // Rev 1.1 - Localparam WR_RECOVERY added and mapped to |
---|
59 | // load mode register. PK. 14/7/08 |
---|
60 | // Rev 1.2 - To issue an Auto Refresh command to each chip during various |
---|
61 | // calibration stages logic modified. PK. 08/10/08 |
---|
62 | // Rev 1.3 - Retain current data pattern for stage 4 calibration, and create |
---|
63 | // new pattern for stage 4. RC. 09/21/09. |
---|
64 | //***************************************************************************** |
---|
65 | |
---|
66 | `timescale 1ns/1ps |
---|
67 | |
---|
68 | module ddr2_phy_init # |
---|
69 | ( |
---|
70 | // Following parameters are for 72-bit RDIMM design (for ML561 Reference |
---|
71 | // board design). Actual values may be different. Actual parameters values |
---|
72 | // are passed from design top module dram module. Please refer to |
---|
73 | // the dram module for actual values. |
---|
74 | parameter BANK_WIDTH = 2, |
---|
75 | parameter CKE_WIDTH = 1, |
---|
76 | parameter COL_WIDTH = 10, |
---|
77 | parameter CS_BITS = 0, |
---|
78 | parameter CS_NUM = 1, |
---|
79 | parameter DQ_WIDTH = 72, |
---|
80 | parameter ODT_WIDTH = 1, |
---|
81 | parameter ROW_WIDTH = 14, |
---|
82 | parameter ADDITIVE_LAT = 0, |
---|
83 | parameter BURST_LEN = 4, |
---|
84 | parameter TWO_T_TIME_EN = 0, |
---|
85 | parameter BURST_TYPE = 0, |
---|
86 | parameter CAS_LAT = 5, |
---|
87 | parameter ODT_TYPE = 1, |
---|
88 | parameter REDUCE_DRV = 0, |
---|
89 | parameter REG_ENABLE = 1, |
---|
90 | parameter TWR = 15000, |
---|
91 | parameter CLK_PERIOD = 3000, |
---|
92 | parameter DDR_TYPE = 1, |
---|
93 | parameter SIM_ONLY = 0 |
---|
94 | ) |
---|
95 | ( |
---|
96 | input clk0, |
---|
97 | input clkdiv0, |
---|
98 | input rst0, |
---|
99 | input rstdiv0, |
---|
100 | input [3:0] calib_done, |
---|
101 | input ctrl_ref_flag, |
---|
102 | input calib_ref_req, |
---|
103 | output reg [3:0] calib_start, |
---|
104 | output reg calib_ref_done, |
---|
105 | output reg phy_init_wren, |
---|
106 | output reg phy_init_rden, |
---|
107 | output [ROW_WIDTH-1:0] phy_init_addr, |
---|
108 | output [BANK_WIDTH-1:0] phy_init_ba, |
---|
109 | output phy_init_ras_n, |
---|
110 | output phy_init_cas_n, |
---|
111 | output phy_init_we_n, |
---|
112 | output [CS_NUM-1:0] phy_init_cs_n, |
---|
113 | output [CKE_WIDTH-1:0] phy_init_cke, |
---|
114 | output reg phy_init_done, |
---|
115 | output phy_init_data_sel |
---|
116 | ); |
---|
117 | |
---|
118 | // time to wait between consecutive commands in PHY_INIT - this is a |
---|
119 | // generic number, and must be large enough to account for worst case |
---|
120 | // timing parameter (tRFC - refresh-to-active) across all memory speed |
---|
121 | // grades and operating frequencies. Expressed in CLKDIV clock cycles. |
---|
122 | localparam CNTNEXT_CMD = 7'b1111111; |
---|
123 | // time to wait between read and read or precharge for stage 3 & 4 |
---|
124 | // the larger CNTNEXT_CMD can also be used, use smaller number to |
---|
125 | // speed up calibration - avoid tRAS violation, and speeds up simulation |
---|
126 | localparam CNTNEXT_RD = 4'b1111; |
---|
127 | |
---|
128 | // Write recovery (WR) time - is defined by |
---|
129 | // tWR (in nanoseconds) by tCK (in nanoseconds) and rounding up a |
---|
130 | // noninteger value to the next integer |
---|
131 | localparam integer WR_RECOVERY = ((TWR + CLK_PERIOD) - 1)/CLK_PERIOD; |
---|
132 | localparam CS_BITS_FIX = (CS_BITS == 0) ? 1 : CS_BITS; |
---|
133 | |
---|
134 | localparam INIT_CAL1_READ = 5'h00; |
---|
135 | localparam INIT_CAL2_READ = 5'h01; |
---|
136 | localparam INIT_CAL3_READ = 5'h02; |
---|
137 | localparam INIT_CAL4_READ = 5'h03; |
---|
138 | localparam INIT_CAL1_WRITE = 5'h04; |
---|
139 | localparam INIT_CAL2_WRITE = 5'h05; |
---|
140 | localparam INIT_CAL3_WRITE = 5'h06; |
---|
141 | localparam INIT_DUMMY_ACTIVE_WAIT = 5'h07; |
---|
142 | localparam INIT_PRECHARGE = 5'h08; |
---|
143 | localparam INIT_LOAD_MODE = 5'h09; |
---|
144 | localparam INIT_AUTO_REFRESH = 5'h0A; |
---|
145 | localparam INIT_IDLE = 5'h0B; |
---|
146 | localparam INIT_CNT_200 = 5'h0C; |
---|
147 | localparam INIT_CNT_200_WAIT = 5'h0D; |
---|
148 | localparam INIT_PRECHARGE_WAIT = 5'h0E; |
---|
149 | localparam INIT_MODE_REGISTER_WAIT = 5'h0F; |
---|
150 | localparam INIT_AUTO_REFRESH_WAIT = 5'h10; |
---|
151 | localparam INIT_DEEP_MEMORY_ST = 5'h11; |
---|
152 | localparam INIT_DUMMY_ACTIVE = 5'h12; |
---|
153 | localparam INIT_CAL1_WRITE_READ = 5'h13; |
---|
154 | localparam INIT_CAL1_READ_WAIT = 5'h14; |
---|
155 | localparam INIT_CAL2_WRITE_READ = 5'h15; |
---|
156 | localparam INIT_CAL2_READ_WAIT = 5'h16; |
---|
157 | localparam INIT_CAL3_WRITE_READ = 5'h17; |
---|
158 | localparam INIT_CAL3_READ_WAIT = 5'h18; |
---|
159 | localparam INIT_CAL4_READ_WAIT = 5'h19; |
---|
160 | localparam INIT_CALIB_REF = 5'h1A; |
---|
161 | localparam INIT_ZQCL = 5'h1B; |
---|
162 | localparam INIT_WAIT_DLLK_ZQINIT = 5'h1C; |
---|
163 | localparam INIT_CAL4_WRITE = 5'h1D; // MIG 3.3: New state |
---|
164 | localparam INIT_CAL4_WRITE_READ = 5'h1E; // MIG 3.3: New state |
---|
165 | |
---|
166 | localparam INIT_CNTR_INIT = 4'h0; |
---|
167 | localparam INIT_CNTR_PRECH_1 = 4'h1; |
---|
168 | localparam INIT_CNTR_EMR2_INIT = 4'h2; |
---|
169 | localparam INIT_CNTR_EMR3_INIT = 4'h3; |
---|
170 | localparam INIT_CNTR_EMR_EN_DLL = 4'h4; |
---|
171 | localparam INIT_CNTR_MR_RST_DLL = 4'h5; |
---|
172 | localparam INIT_CNTR_CNT_200_WAIT = 4'h6; |
---|
173 | localparam INIT_CNTR_PRECH_2 = 4'h7; |
---|
174 | localparam INIT_CNTR_AR_1 = 4'h8; |
---|
175 | localparam INIT_CNTR_AR_2 = 4'h9; |
---|
176 | localparam INIT_CNTR_MR_ACT_DLL = 4'hA; |
---|
177 | localparam INIT_CNTR_EMR_DEF_OCD = 4'hB; |
---|
178 | localparam INIT_CNTR_EMR_EXIT_OCD = 4'hC; |
---|
179 | localparam INIT_CNTR_DEEP_MEM = 4'hD; |
---|
180 | // MIG 3.3: Remove extra precharge occurring at end of calibration |
---|
181 | // localparam INIT_CNTR_PRECH_3 = 4'hE; |
---|
182 | // localparam INIT_CNTR_DONE = 4'hF; |
---|
183 | localparam INIT_CNTR_DONE = 4'hE; |
---|
184 | |
---|
185 | localparam DDR1 = 0; |
---|
186 | localparam DDR2 = 1; |
---|
187 | localparam DDR3 = 2; |
---|
188 | |
---|
189 | reg [CS_BITS_FIX :0] auto_cnt_r; |
---|
190 | reg [1:0] burst_addr_r; |
---|
191 | reg [1:0] burst_cnt_r; |
---|
192 | wire [1:0] burst_val; |
---|
193 | wire cal_read; |
---|
194 | wire cal_write; |
---|
195 | wire cal_write_read; |
---|
196 | reg cal1_started_r; |
---|
197 | reg cal2_started_r; |
---|
198 | reg cal4_started_r; |
---|
199 | reg [3:0] calib_done_r; |
---|
200 | reg calib_ref_req_posedge; |
---|
201 | reg calib_ref_req_r; |
---|
202 | reg [15:0] calib_start_shift0_r; |
---|
203 | reg [15:0] calib_start_shift1_r; |
---|
204 | reg [15:0] calib_start_shift2_r; |
---|
205 | reg [15:0] calib_start_shift3_r; |
---|
206 | reg [1:0] chip_cnt_r; |
---|
207 | reg [4:0] cke_200us_cnt_r; |
---|
208 | reg cke_200us_cnt_en_r; |
---|
209 | reg [7:0] cnt_200_cycle_r; |
---|
210 | reg cnt_200_cycle_done_r; |
---|
211 | reg [6:0] cnt_cmd_r; |
---|
212 | reg cnt_cmd_ok_r; |
---|
213 | reg [3:0] cnt_rd_r; |
---|
214 | reg cnt_rd_ok_r; |
---|
215 | reg ctrl_ref_flag_r; |
---|
216 | reg done_200us_r; |
---|
217 | reg [ROW_WIDTH-1:0] ddr_addr_r; |
---|
218 | reg [ROW_WIDTH-1:0] ddr_addr_r1; |
---|
219 | reg [BANK_WIDTH-1:0] ddr_ba_r; |
---|
220 | reg [BANK_WIDTH-1:0] ddr_ba_r1; |
---|
221 | reg ddr_cas_n_r; |
---|
222 | reg ddr_cas_n_r1; |
---|
223 | reg [CKE_WIDTH-1:0] ddr_cke_r; |
---|
224 | reg [CS_NUM-1:0] ddr_cs_n_r; |
---|
225 | reg [CS_NUM-1:0] ddr_cs_n_r1; |
---|
226 | reg [CS_NUM-1:0] ddr_cs_disable_r; |
---|
227 | reg ddr_ras_n_r; |
---|
228 | reg ddr_ras_n_r1; |
---|
229 | reg ddr_we_n_r; |
---|
230 | reg ddr_we_n_r1; |
---|
231 | wire [15:0] ext_mode_reg; |
---|
232 | reg [3:0] init_cnt_r; |
---|
233 | reg init_done_r; |
---|
234 | reg [4:0] init_next_state; |
---|
235 | reg [4:0] init_state_r; |
---|
236 | reg [4:0] init_state_r1; |
---|
237 | reg [4:0] init_state_r1_2t; |
---|
238 | reg [4:0] init_state_r2; |
---|
239 | wire [15:0] load_mode_reg; |
---|
240 | wire [15:0] load_mode_reg0; |
---|
241 | wire [15:0] load_mode_reg1; |
---|
242 | wire [15:0] load_mode_reg2; |
---|
243 | wire [15:0] load_mode_reg3; |
---|
244 | reg phy_init_done_r; |
---|
245 | reg phy_init_done_r1; |
---|
246 | reg phy_init_done_r2; |
---|
247 | reg phy_init_done_r3; |
---|
248 | reg refresh_req; |
---|
249 | wire [3:0] start_cal; |
---|
250 | |
---|
251 | //*************************************************************************** |
---|
252 | |
---|
253 | //***************************************************************** |
---|
254 | // DDR1 and DDR2 Load mode register |
---|
255 | // Mode Register (MR): |
---|
256 | // [15:14] - unused - 00 |
---|
257 | // [13] - reserved - 0 |
---|
258 | // [12] - Power-down mode - 0 (normal) |
---|
259 | // [11:9] - write recovery - for Auto Precharge (tWR/tCK) |
---|
260 | // [8] - DLL reset - 0 or 1 |
---|
261 | // [7] - Test Mode - 0 (normal) |
---|
262 | // [6:4] - CAS latency - CAS_LAT |
---|
263 | // [3] - Burst Type - BURST_TYPE |
---|
264 | // [2:0] - Burst Length - BURST_LEN |
---|
265 | //***************************************************************** |
---|
266 | |
---|
267 | generate |
---|
268 | if (DDR_TYPE == DDR2) begin: gen_load_mode_reg_ddr2 |
---|
269 | assign load_mode_reg[2:0] = (BURST_LEN == 8) ? 3'b011 : |
---|
270 | ((BURST_LEN == 4) ? 3'b010 : 3'b111); |
---|
271 | assign load_mode_reg[3] = BURST_TYPE; |
---|
272 | assign load_mode_reg[6:4] = (CAS_LAT == 3) ? 3'b011 : |
---|
273 | ((CAS_LAT == 4) ? 3'b100 : |
---|
274 | ((CAS_LAT == 5) ? 3'b101 : 3'b111)); |
---|
275 | assign load_mode_reg[7] = 1'b0; |
---|
276 | assign load_mode_reg[8] = 1'b0; // init value only (DLL not reset) |
---|
277 | assign load_mode_reg[11:9] = (WR_RECOVERY == 6) ? 3'b101 : |
---|
278 | ((WR_RECOVERY == 5) ? 3'b100 : |
---|
279 | ((WR_RECOVERY == 4) ? 3'b011 : |
---|
280 | ((WR_RECOVERY == 3) ? 3'b010 : |
---|
281 | 3'b001))); |
---|
282 | assign load_mode_reg[15:12] = 4'b000; |
---|
283 | end else if (DDR_TYPE == DDR1)begin: gen_load_mode_reg_ddr1 |
---|
284 | assign load_mode_reg[2:0] = (BURST_LEN == 8) ? 3'b011 : |
---|
285 | ((BURST_LEN == 4) ? 3'b010 : |
---|
286 | ((BURST_LEN == 2) ? 3'b001 : 3'b111)); |
---|
287 | assign load_mode_reg[3] = BURST_TYPE; |
---|
288 | assign load_mode_reg[6:4] = (CAS_LAT == 2) ? 3'b010 : |
---|
289 | ((CAS_LAT == 3) ? 3'b011 : |
---|
290 | ((CAS_LAT == 25) ? 3'b110 : 3'b111)); |
---|
291 | assign load_mode_reg[12:7] = 6'b000000; // init value only |
---|
292 | assign load_mode_reg[15:13] = 3'b000; |
---|
293 | end |
---|
294 | endgenerate |
---|
295 | |
---|
296 | //***************************************************************** |
---|
297 | // DDR1 and DDR2 ext mode register |
---|
298 | // Extended Mode Register (MR): |
---|
299 | // [15:14] - unused - 00 |
---|
300 | // [13] - reserved - 0 |
---|
301 | // [12] - output enable - 0 (enabled) |
---|
302 | // [11] - RDQS enable - 0 (disabled) |
---|
303 | // [10] - DQS# enable - 0 (enabled) |
---|
304 | // [9:7] - OCD Program - 111 or 000 (first 111, then 000 during init) |
---|
305 | // [6] - RTT[1] - RTT[1:0] = 0(no ODT), 1(75), 2(150), 3(50) |
---|
306 | // [5:3] - Additive CAS - ADDITIVE_CAS |
---|
307 | // [2] - RTT[0] |
---|
308 | // [1] - Output drive - REDUCE_DRV (= 0(full), = 1 (reduced) |
---|
309 | // [0] - DLL enable - 0 (normal) |
---|
310 | //***************************************************************** |
---|
311 | |
---|
312 | generate |
---|
313 | if (DDR_TYPE == DDR2) begin: gen_ext_mode_reg_ddr2 |
---|
314 | assign ext_mode_reg[0] = 1'b0; |
---|
315 | assign ext_mode_reg[1] = REDUCE_DRV; |
---|
316 | assign ext_mode_reg[2] = ((ODT_TYPE == 1) || (ODT_TYPE == 3)) ? |
---|
317 | 1'b1 : 1'b0; |
---|
318 | assign ext_mode_reg[5:3] = (ADDITIVE_LAT == 0) ? 3'b000 : |
---|
319 | ((ADDITIVE_LAT == 1) ? 3'b001 : |
---|
320 | ((ADDITIVE_LAT == 2) ? 3'b010 : |
---|
321 | ((ADDITIVE_LAT == 3) ? 3'b011 : |
---|
322 | ((ADDITIVE_LAT == 4) ? 3'b100 : |
---|
323 | 3'b111)))); |
---|
324 | assign ext_mode_reg[6] = ((ODT_TYPE == 2) || (ODT_TYPE == 3)) ? |
---|
325 | 1'b1 : 1'b0; |
---|
326 | assign ext_mode_reg[9:7] = 3'b000; |
---|
327 | assign ext_mode_reg[10] = 1'b0; |
---|
328 | assign ext_mode_reg[15:10] = 6'b000000; |
---|
329 | end else if (DDR_TYPE == DDR1) begin: gen_ext_mode_reg_ddr1 |
---|
330 | assign ext_mode_reg[0] = 1'b0; |
---|
331 | assign ext_mode_reg[1] = REDUCE_DRV; |
---|
332 | assign ext_mode_reg[12:2] = 11'b00000000000; |
---|
333 | assign ext_mode_reg[15:13] = 3'b000; |
---|
334 | end |
---|
335 | endgenerate |
---|
336 | |
---|
337 | //***************************************************************** |
---|
338 | // DDR3 Load mode reg0 |
---|
339 | // Mode Register (MR0): |
---|
340 | // [15:13] - unused - 000 |
---|
341 | // [12] - Precharge Power-down DLL usage - 0 (DLL frozen, slow-exit), |
---|
342 | // 1 (DLL maintained) |
---|
343 | // [11:9] - write recovery for Auto Precharge (tWR/tCK = 6) |
---|
344 | // [8] - DLL reset - 0 or 1 |
---|
345 | // [7] - Test Mode - 0 (normal) |
---|
346 | // [6:4],[2] - CAS latency - CAS_LAT |
---|
347 | // [3] - Burst Type - BURST_TYPE |
---|
348 | // [1:0] - Burst Length - BURST_LEN |
---|
349 | //***************************************************************** |
---|
350 | |
---|
351 | generate |
---|
352 | if (DDR_TYPE == DDR3) begin: gen_load_mode_reg0_ddr3 |
---|
353 | assign load_mode_reg0[1:0] = (BURST_LEN == 8) ? 2'b00 : |
---|
354 | ((BURST_LEN == 4) ? 2'b10 : 2'b11); |
---|
355 | // Part of CAS latency. This bit is '0' for all CAS latencies |
---|
356 | assign load_mode_reg0[2] = 1'b0; |
---|
357 | assign load_mode_reg0[3] = BURST_TYPE; |
---|
358 | assign load_mode_reg0[6:4] = (CAS_LAT == 5) ? 3'b001 : |
---|
359 | (CAS_LAT == 6) ? 3'b010 : 3'b111; |
---|
360 | assign load_mode_reg0[7] = 1'b0; |
---|
361 | // init value only (DLL reset) |
---|
362 | assign load_mode_reg0[8] = 1'b1; |
---|
363 | assign load_mode_reg0[11:9] = 3'b010; |
---|
364 | // Precharge Power-Down DLL 'slow-exit' |
---|
365 | assign load_mode_reg0[12] = 1'b0; |
---|
366 | assign load_mode_reg0[15:13] = 3'b000; |
---|
367 | end |
---|
368 | endgenerate |
---|
369 | |
---|
370 | //***************************************************************** |
---|
371 | // DDR3 Load mode reg1 |
---|
372 | // Mode Register (MR1): |
---|
373 | // [15:13] - unused - 00 |
---|
374 | // [12] - output enable - 0 (enabled for DQ, DQS, DQS#) |
---|
375 | // [11] - TDQS enable - 0 (TDQS disabled and DM enabled) |
---|
376 | // [10] - reserved - 0 (must be '0') |
---|
377 | // [9] - RTT[2] - 0 |
---|
378 | // [8] - reserved - 0 (must be '0') |
---|
379 | // [7] - write leveling - 0 (disabled), 1 (enabled) |
---|
380 | // [6] - RTT[1] - RTT[1:0] = 0(no ODT), 1(75), 2(150), 3(50) |
---|
381 | // [5] - Output driver impedance[1] - 0 (RZQ/6 and RZQ/7) |
---|
382 | // [4:3] - Additive CAS - ADDITIVE_CAS |
---|
383 | // [2] - RTT[0] |
---|
384 | // [1] - Output driver impedance[0] - 0(RZQ/6), or 1 (RZQ/7) |
---|
385 | // [0] - DLL enable - 0 (normal) |
---|
386 | //***************************************************************** |
---|
387 | |
---|
388 | generate |
---|
389 | if (DDR_TYPE == DDR3) begin: gen_ext_mode_reg1_ddr3 |
---|
390 | // DLL enabled during Imitialization |
---|
391 | assign load_mode_reg1[0] = 1'b0; |
---|
392 | // RZQ/6 |
---|
393 | assign load_mode_reg1[1] = REDUCE_DRV; |
---|
394 | assign load_mode_reg1[2] = ((ODT_TYPE == 1) || (ODT_TYPE == 3)) ? |
---|
395 | 1'b1 : 1'b0; |
---|
396 | assign load_mode_reg1[4:3] = (ADDITIVE_LAT == 0) ? 2'b00 : |
---|
397 | ((ADDITIVE_LAT == 1) ? 2'b01 : |
---|
398 | ((ADDITIVE_LAT == 2) ? 2'b10 : |
---|
399 | 3'b111)); |
---|
400 | // RZQ/6 |
---|
401 | assign load_mode_reg1[5] = 1'b0; |
---|
402 | assign load_mode_reg1[6] = ((ODT_TYPE == 2) || (ODT_TYPE == 3)) ? |
---|
403 | 1'b1 : 1'b0; |
---|
404 | // Make zero WRITE_LEVEL |
---|
405 | assign load_mode_reg1[7] = 0; |
---|
406 | assign load_mode_reg1[8] = 1'b0; |
---|
407 | assign load_mode_reg1[9] = 1'b0; |
---|
408 | assign load_mode_reg1[10] = 1'b0; |
---|
409 | assign load_mode_reg1[15:11] = 5'b00000; |
---|
410 | end |
---|
411 | endgenerate |
---|
412 | |
---|
413 | //***************************************************************** |
---|
414 | // DDR3 Load mode reg2 |
---|
415 | // Mode Register (MR2): |
---|
416 | // [15:11] - unused - 00 |
---|
417 | // [10:9] - RTT_WR - 00 (Dynamic ODT off) |
---|
418 | // [8] - reserved - 0 (must be '0') |
---|
419 | // [7] - self-refresh temperature range - |
---|
420 | // 0 (normal), 1 (extended) |
---|
421 | // [6] - Auto Self-Refresh - 0 (manual), 1(auto) |
---|
422 | // [5:3] - CAS Write Latency (CWL) - |
---|
423 | // 000 (5 for 400 MHz device), |
---|
424 | // 001 (6 for 400 MHz to 533 MHz devices), |
---|
425 | // 010 (7 for 533 MHz to 667 MHz devices), |
---|
426 | // 011 (8 for 667 MHz to 800 MHz) |
---|
427 | // [2:0] - Partial Array Self-Refresh (Optional) - |
---|
428 | // 000 (full array) |
---|
429 | //***************************************************************** |
---|
430 | |
---|
431 | generate |
---|
432 | if (DDR_TYPE == DDR3) begin: gen_ext_mode_reg2_ddr3 |
---|
433 | assign load_mode_reg2[2:0] = 3'b000; |
---|
434 | assign load_mode_reg2[5:3] = (CAS_LAT == 5) ? 3'b000 : |
---|
435 | (CAS_LAT == 6) ? 3'b001 : 3'b111; |
---|
436 | assign load_mode_reg2[6] = 1'b0; // Manual Self-Refresh |
---|
437 | assign load_mode_reg2[7] = 1'b0; |
---|
438 | assign load_mode_reg2[8] = 1'b0; |
---|
439 | assign load_mode_reg2[10:9] = 2'b00; |
---|
440 | assign load_mode_reg2[15:11] = 5'b00000; |
---|
441 | end |
---|
442 | endgenerate |
---|
443 | |
---|
444 | //***************************************************************** |
---|
445 | // DDR3 Load mode reg3 |
---|
446 | // Mode Register (MR3): |
---|
447 | // [15:3] - unused - All zeros |
---|
448 | // [2] - MPR Operation - 0(normal operation), 1(data flow from MPR) |
---|
449 | // [1:0] - MPR location - 00 (Predefined pattern) |
---|
450 | //***************************************************************** |
---|
451 | |
---|
452 | generate |
---|
453 | if (DDR_TYPE == DDR3)begin: gen_ext_mode_reg3_ddr3 |
---|
454 | assign load_mode_reg3[1:0] = 2'b00; |
---|
455 | assign load_mode_reg3[2] = 1'b0; |
---|
456 | assign load_mode_reg3[15:3] = 13'b0000000000000; |
---|
457 | end |
---|
458 | endgenerate |
---|
459 | |
---|
460 | //*************************************************************************** |
---|
461 | // Logic for calibration start, and for auto-refresh during cal request |
---|
462 | // CALIB_REF_REQ is used by calibration logic to request auto-refresh |
---|
463 | // durign calibration (used to avoid tRAS violation is certain calibration |
---|
464 | // stages take a long time). Once the auto-refresh is complete and cal can |
---|
465 | // be resumed, CALIB_REF_DONE is asserted by PHY_INIT. |
---|
466 | //*************************************************************************** |
---|
467 | |
---|
468 | // generate pulse for each of calibration start controls |
---|
469 | assign start_cal[0] = ((init_state_r1 == INIT_CAL1_READ) && |
---|
470 | (init_state_r2 != INIT_CAL1_READ)); |
---|
471 | assign start_cal[1] = ((init_state_r1 == INIT_CAL2_READ) && |
---|
472 | (init_state_r2 != INIT_CAL2_READ)); |
---|
473 | assign start_cal[2] = ((init_state_r1 == INIT_CAL3_READ) && |
---|
474 | (init_state_r2 == INIT_CAL3_WRITE_READ)); |
---|
475 | assign start_cal[3] = ((init_state_r1 == INIT_CAL4_READ) && |
---|
476 | (init_state_r2 != INIT_CAL4_READ)); |
---|
477 | // MIG 3.3: Change to accomodate FSM changes related to stage 4 calibration |
---|
478 | // (init_state_r2 == INIT_CAL4_WRITE_READ)); |
---|
479 | |
---|
480 | // Generate positive-edge triggered, latched signal to force initialization |
---|
481 | // to pause calibration, and to issue auto-refresh. Clear flag as soon as |
---|
482 | // refresh initiated |
---|
483 | always @(posedge clkdiv0) |
---|
484 | if (rstdiv0) begin |
---|
485 | calib_ref_req_r <= 1'b0; |
---|
486 | calib_ref_req_posedge <= 1'b0; |
---|
487 | refresh_req <= 1'b0; |
---|
488 | end else begin |
---|
489 | calib_ref_req_r <= calib_ref_req; |
---|
490 | calib_ref_req_posedge <= calib_ref_req & ~calib_ref_req_r; |
---|
491 | if (init_state_r1 == INIT_AUTO_REFRESH) |
---|
492 | refresh_req <= 1'b0; |
---|
493 | else if (calib_ref_req_posedge) |
---|
494 | refresh_req <= 1'b1; |
---|
495 | end |
---|
496 | |
---|
497 | // flag to tell cal1 calibration was started. |
---|
498 | // This flag is used for cal1 auto refreshes |
---|
499 | // some of these bits may not be needed - only needed for those stages that |
---|
500 | // need refreshes within the stage (i.e. very long stages) |
---|
501 | always @(posedge clkdiv0) |
---|
502 | if (rstdiv0) begin |
---|
503 | cal1_started_r <= 1'b0; |
---|
504 | cal2_started_r <= 1'b0; |
---|
505 | cal4_started_r <= 1'b0; |
---|
506 | end else begin |
---|
507 | if (calib_start[0]) |
---|
508 | cal1_started_r <= 1'b1; |
---|
509 | if (calib_start[1]) |
---|
510 | cal2_started_r <= 1'b1; |
---|
511 | if (calib_start[3]) |
---|
512 | cal4_started_r <= 1'b1; |
---|
513 | end |
---|
514 | |
---|
515 | // Delay start of each calibration by 16 clock cycles to |
---|
516 | // ensure that when calibration logic begins, that read data is already |
---|
517 | // appearing on the bus. Don't really need it, it's more for simulation |
---|
518 | // purposes. Each circuit should synthesize using an SRL16. |
---|
519 | // In first stage of calibration periodic auto refreshes |
---|
520 | // will be issued to meet memory timing. calib_start_shift0_r[15] will be |
---|
521 | // asserted more than once.calib_start[0] is anded with cal1_started_r so |
---|
522 | // that it is asserted only once. cal1_refresh_done is anded with |
---|
523 | // cal1_started_r so that it is asserted after the auto refreshes. |
---|
524 | always @(posedge clkdiv0) begin |
---|
525 | calib_start_shift0_r <= {calib_start_shift0_r[14:0], start_cal[0]}; |
---|
526 | calib_start_shift1_r <= {calib_start_shift1_r[14:0], start_cal[1]}; |
---|
527 | calib_start_shift2_r <= {calib_start_shift2_r[14:0], start_cal[2]}; |
---|
528 | calib_start_shift3_r <= {calib_start_shift3_r[14:0], start_cal[3]}; |
---|
529 | calib_start[0] <= calib_start_shift0_r[15] & ~cal1_started_r; |
---|
530 | calib_start[1] <= calib_start_shift1_r[15] & ~cal2_started_r; |
---|
531 | calib_start[2] <= calib_start_shift2_r[15]; |
---|
532 | calib_start[3] <= calib_start_shift3_r[15] & ~cal4_started_r; |
---|
533 | calib_ref_done <= calib_start_shift0_r[15] | |
---|
534 | calib_start_shift1_r[15] | |
---|
535 | calib_start_shift3_r[15]; |
---|
536 | end |
---|
537 | |
---|
538 | // generate delay for various states that require it (no maximum delay |
---|
539 | // requirement, make sure that terminal count is large enough to cover |
---|
540 | // all cases) |
---|
541 | always @(posedge clkdiv0) begin |
---|
542 | case (init_state_r) |
---|
543 | INIT_PRECHARGE_WAIT, |
---|
544 | INIT_MODE_REGISTER_WAIT, |
---|
545 | INIT_AUTO_REFRESH_WAIT, |
---|
546 | INIT_DUMMY_ACTIVE_WAIT, |
---|
547 | INIT_CAL1_WRITE_READ, |
---|
548 | INIT_CAL1_READ_WAIT, |
---|
549 | INIT_CAL2_WRITE_READ, |
---|
550 | INIT_CAL2_READ_WAIT, |
---|
551 | INIT_CAL3_WRITE_READ, |
---|
552 | INIT_CAL4_WRITE_READ : |
---|
553 | cnt_cmd_r <= cnt_cmd_r + 1; |
---|
554 | default: |
---|
555 | cnt_cmd_r <= 7'b0000000; |
---|
556 | endcase |
---|
557 | end |
---|
558 | |
---|
559 | // assert when count reaches the value |
---|
560 | always @(posedge clkdiv0) begin |
---|
561 | if(cnt_cmd_r == CNTNEXT_CMD) |
---|
562 | cnt_cmd_ok_r <= 1'b1; |
---|
563 | else |
---|
564 | cnt_cmd_ok_r <= 1'b0; |
---|
565 | end |
---|
566 | |
---|
567 | always @(posedge clkdiv0) begin |
---|
568 | case (init_state_r) |
---|
569 | INIT_CAL3_READ_WAIT, |
---|
570 | INIT_CAL4_READ_WAIT: |
---|
571 | cnt_rd_r <= cnt_rd_r + 1; |
---|
572 | default: |
---|
573 | cnt_rd_r <= 4'b0000; |
---|
574 | endcase |
---|
575 | end |
---|
576 | |
---|
577 | always @(posedge clkdiv0) begin |
---|
578 | if(cnt_rd_r == CNTNEXT_RD) |
---|
579 | cnt_rd_ok_r <= 1'b1; |
---|
580 | else |
---|
581 | cnt_rd_ok_r <= 1'b0; |
---|
582 | end |
---|
583 | |
---|
584 | //*************************************************************************** |
---|
585 | // Initial delay after power-on |
---|
586 | //*************************************************************************** |
---|
587 | |
---|
588 | // register the refresh flag from the controller. |
---|
589 | // The refresh flag is in full frequency domain - so a pulsed version must |
---|
590 | // be generated for half freq domain using 2 consecutive full clk cycles |
---|
591 | // The registered version is used for the 200us counter |
---|
592 | always @(posedge clk0) |
---|
593 | ctrl_ref_flag_r <= ctrl_ref_flag; |
---|
594 | always @(posedge clkdiv0) |
---|
595 | cke_200us_cnt_en_r <= ctrl_ref_flag || ctrl_ref_flag_r; |
---|
596 | |
---|
597 | // 200us counter for cke |
---|
598 | always @(posedge clkdiv0) |
---|
599 | if (rstdiv0) begin |
---|
600 | // skip power-up count if only simulating |
---|
601 | if (SIM_ONLY) |
---|
602 | cke_200us_cnt_r <= 5'b00001; |
---|
603 | else |
---|
604 | cke_200us_cnt_r <= 5'd27; |
---|
605 | end else if (cke_200us_cnt_en_r) |
---|
606 | cke_200us_cnt_r <= cke_200us_cnt_r - 1; |
---|
607 | |
---|
608 | always @(posedge clkdiv0) |
---|
609 | if (rstdiv0) |
---|
610 | done_200us_r <= 1'b0; |
---|
611 | else if (!done_200us_r) |
---|
612 | done_200us_r <= (cke_200us_cnt_r == 5'b00000); |
---|
613 | |
---|
614 | // 200 clocks counter - count value : h'64 required for initialization |
---|
615 | // Counts 100 divided by two clocks |
---|
616 | always @(posedge clkdiv0) |
---|
617 | if (rstdiv0 || (init_state_r == INIT_CNT_200)) |
---|
618 | cnt_200_cycle_r <= 8'h64; |
---|
619 | else if (init_state_r == INIT_ZQCL) // ddr3 |
---|
620 | cnt_200_cycle_r <= 8'hC8; |
---|
621 | else if (cnt_200_cycle_r != 8'h00) |
---|
622 | cnt_200_cycle_r <= cnt_200_cycle_r - 1; |
---|
623 | |
---|
624 | always @(posedge clkdiv0) |
---|
625 | if (rstdiv0 || (init_state_r == INIT_CNT_200) |
---|
626 | || (init_state_r == INIT_ZQCL)) |
---|
627 | cnt_200_cycle_done_r <= 1'b0; |
---|
628 | else if (cnt_200_cycle_r == 8'h00) |
---|
629 | cnt_200_cycle_done_r <= 1'b1; |
---|
630 | |
---|
631 | //***************************************************************** |
---|
632 | // handle deep memory configuration: |
---|
633 | // During initialization: Repeat initialization sequence once for each |
---|
634 | // chip select. Note that we could perform initalization for all chip |
---|
635 | // selects simulataneously. Probably fine - any potential SI issues with |
---|
636 | // auto refreshing all chip selects at once? |
---|
637 | // Once initialization complete, assert only CS[1] for calibration. |
---|
638 | //***************************************************************** |
---|
639 | |
---|
640 | always @(posedge clkdiv0) |
---|
641 | if (rstdiv0) begin |
---|
642 | chip_cnt_r <= 2'b00; |
---|
643 | end else if (init_state_r == INIT_DEEP_MEMORY_ST) begin |
---|
644 | if (chip_cnt_r != CS_NUM) |
---|
645 | chip_cnt_r <= chip_cnt_r + 1; |
---|
646 | else |
---|
647 | chip_cnt_r <= 2'b00; |
---|
648 | // MIG 2.4: Modified to issue an Auto Refresh commmand |
---|
649 | // to each chip select during various calibration stages |
---|
650 | end else if (init_state_r == INIT_PRECHARGE && init_done_r) begin |
---|
651 | chip_cnt_r <= 2'b00; |
---|
652 | end else if (init_state_r1 == INIT_AUTO_REFRESH && init_done_r) begin |
---|
653 | if (chip_cnt_r < (CS_NUM-1)) |
---|
654 | chip_cnt_r <= chip_cnt_r + 1; |
---|
655 | end |
---|
656 | |
---|
657 | // keep track of which chip selects got auto-refreshed (avoid auto-refreshing |
---|
658 | // all CS's at once to avoid current spike) |
---|
659 | always @(posedge clkdiv0)begin |
---|
660 | if (rstdiv0 || init_state_r == INIT_PRECHARGE) |
---|
661 | auto_cnt_r <= 'd0; |
---|
662 | else if (init_state_r == INIT_AUTO_REFRESH && init_done_r) begin |
---|
663 | if (auto_cnt_r < CS_NUM) |
---|
664 | auto_cnt_r <= auto_cnt_r + 1; |
---|
665 | end |
---|
666 | end |
---|
667 | |
---|
668 | always @(posedge clkdiv0) |
---|
669 | if (rstdiv0) begin |
---|
670 | ddr_cs_n_r <= {CS_NUM{1'b1}}; |
---|
671 | end else begin |
---|
672 | ddr_cs_n_r <= {CS_NUM{1'b1}}; |
---|
673 | if ((init_state_r == INIT_DUMMY_ACTIVE) || |
---|
674 | ((init_state_r == INIT_PRECHARGE) && (~init_done_r))|| |
---|
675 | (init_state_r == INIT_LOAD_MODE) || |
---|
676 | (init_state_r == INIT_AUTO_REFRESH) || |
---|
677 | (init_state_r == INIT_ZQCL ) || |
---|
678 | (((init_state_r == INIT_CAL1_READ) || |
---|
679 | (init_state_r == INIT_CAL2_READ) || |
---|
680 | (init_state_r == INIT_CAL3_READ) || |
---|
681 | (init_state_r == INIT_CAL4_READ) || |
---|
682 | (init_state_r == INIT_CAL1_WRITE) || |
---|
683 | (init_state_r == INIT_CAL2_WRITE) || |
---|
684 | (init_state_r == INIT_CAL3_WRITE) || |
---|
685 | (init_state_r == INIT_CAL4_WRITE)) && (burst_cnt_r == 2'b00))) |
---|
686 | ddr_cs_n_r[chip_cnt_r] <= 1'b0; |
---|
687 | else if (init_state_r == INIT_PRECHARGE) |
---|
688 | ddr_cs_n_r <= {CS_NUM{1'b0}}; |
---|
689 | else |
---|
690 | ddr_cs_n_r[chip_cnt_r] <= 1'b1; |
---|
691 | end |
---|
692 | |
---|
693 | //*************************************************************************** |
---|
694 | // Write/read burst logic |
---|
695 | //*************************************************************************** |
---|
696 | |
---|
697 | assign cal_write = ((init_state_r == INIT_CAL1_WRITE) || |
---|
698 | (init_state_r == INIT_CAL2_WRITE) || |
---|
699 | (init_state_r == INIT_CAL3_WRITE) || |
---|
700 | (init_state_r == INIT_CAL4_WRITE)); |
---|
701 | assign cal_read = ((init_state_r == INIT_CAL1_READ) || |
---|
702 | (init_state_r == INIT_CAL2_READ) || |
---|
703 | (init_state_r == INIT_CAL3_READ) || |
---|
704 | (init_state_r == INIT_CAL4_READ)); |
---|
705 | assign cal_write_read = ((init_state_r == INIT_CAL1_READ) || |
---|
706 | (init_state_r == INIT_CAL2_READ) || |
---|
707 | (init_state_r == INIT_CAL3_READ) || |
---|
708 | (init_state_r == INIT_CAL4_READ) || |
---|
709 | (init_state_r == INIT_CAL1_WRITE) || |
---|
710 | (init_state_r == INIT_CAL2_WRITE) || |
---|
711 | (init_state_r == INIT_CAL3_WRITE) || |
---|
712 | (init_state_r == INIT_CAL4_WRITE)); |
---|
713 | |
---|
714 | assign burst_val = (BURST_LEN == 4) ? 2'b00 : |
---|
715 | (BURST_LEN == 8) ? 2'b01 : 2'b00; |
---|
716 | |
---|
717 | // keep track of current address - need this if burst length < 8 for |
---|
718 | // stage 2-4 calibration writes and reads. Make sure value always gets |
---|
719 | // initialized to 0 before we enter write/read state. This is used to |
---|
720 | // keep track of when another burst must be issued |
---|
721 | always @(posedge clkdiv0) |
---|
722 | if (cal_write_read) |
---|
723 | burst_addr_r <= burst_addr_r + 2; |
---|
724 | else |
---|
725 | burst_addr_r <= 2'b00; |
---|
726 | |
---|
727 | // write/read burst count |
---|
728 | always @(posedge clkdiv0) |
---|
729 | if (cal_write_read) |
---|
730 | if (burst_cnt_r == 2'b00) |
---|
731 | burst_cnt_r <= burst_val; |
---|
732 | else // SHOULD THIS BE -2 CHECK THIS LOGIC |
---|
733 | burst_cnt_r <= burst_cnt_r - 1; |
---|
734 | else |
---|
735 | burst_cnt_r <= 2'b00; |
---|
736 | |
---|
737 | // indicate when a write is occurring |
---|
738 | always @(posedge clkdiv0) |
---|
739 | // MIG 2.1: Remove (burst_addr_r<4) term - not used |
---|
740 | // phy_init_wren <= cal_write && (burst_addr_r < 3'd4); |
---|
741 | phy_init_wren <= cal_write; |
---|
742 | |
---|
743 | // used for read enable calibration, pulse to indicate when read issued |
---|
744 | always @(posedge clkdiv0) |
---|
745 | // MIG 2.1: Remove (burst_addr_r<4) term - not used |
---|
746 | // phy_init_rden <= cal_read && (burst_addr_r < 3'd4); |
---|
747 | phy_init_rden <= cal_read; |
---|
748 | |
---|
749 | //*************************************************************************** |
---|
750 | // Initialization state machine |
---|
751 | //*************************************************************************** |
---|
752 | |
---|
753 | always @(posedge clkdiv0) |
---|
754 | // every time we need to initialize another rank of memory, need to |
---|
755 | // reset init count, and repeat the entire initialization (but not |
---|
756 | // calibration) sequence |
---|
757 | if (rstdiv0 || (init_state_r == INIT_DEEP_MEMORY_ST)) |
---|
758 | init_cnt_r <= INIT_CNTR_INIT; |
---|
759 | else if ((DDR_TYPE == DDR1) && (init_state_r == INIT_PRECHARGE) && |
---|
760 | (init_cnt_r == INIT_CNTR_PRECH_1)) |
---|
761 | // skip EMR(2) and EMR(3) register loads |
---|
762 | init_cnt_r <= INIT_CNTR_EMR_EN_DLL; |
---|
763 | else if ((DDR_TYPE == DDR1) && (init_state_r == INIT_LOAD_MODE) && |
---|
764 | (init_cnt_r == INIT_CNTR_MR_ACT_DLL)) |
---|
765 | // skip OCD calibration for DDR1 |
---|
766 | init_cnt_r <= INIT_CNTR_DEEP_MEM; |
---|
767 | else if ((DDR_TYPE == DDR3) && (init_state_r == INIT_ZQCL)) |
---|
768 | // skip states for DDR3 |
---|
769 | init_cnt_r <= INIT_CNTR_DEEP_MEM; |
---|
770 | else if ((init_state_r == INIT_LOAD_MODE) || |
---|
771 | ((init_state_r == INIT_PRECHARGE) && |
---|
772 | (init_state_r1 != INIT_CALIB_REF)) || |
---|
773 | ((init_state_r == INIT_AUTO_REFRESH) && (~init_done_r)) || |
---|
774 | (init_state_r == INIT_CNT_200) || |
---|
775 | // MIG 3.3: Added increment when starting calibration |
---|
776 | ((init_state_r == INIT_DUMMY_ACTIVE) && |
---|
777 | (init_state_r1 == INIT_IDLE))) |
---|
778 | init_cnt_r <= init_cnt_r + 1; |
---|
779 | |
---|
780 | always @(posedge clkdiv0) begin |
---|
781 | if ((init_state_r == INIT_IDLE) && (init_cnt_r == INIT_CNTR_DONE)) begin |
---|
782 | phy_init_done_r <= 1'b1; |
---|
783 | end else |
---|
784 | phy_init_done_r <= 1'b0; |
---|
785 | end |
---|
786 | |
---|
787 | // phy_init_done to the controller and the user interface. |
---|
788 | // It is delayed by four clocks to account for the |
---|
789 | // multi cycle path constraint to the (phy_init_data_sel) |
---|
790 | // to the phy layer. |
---|
791 | always @(posedge clkdiv0) begin |
---|
792 | phy_init_done_r1 <= phy_init_done_r; |
---|
793 | phy_init_done_r2 <= phy_init_done_r1; |
---|
794 | phy_init_done_r3 <= phy_init_done_r2; |
---|
795 | phy_init_done <= phy_init_done_r3; |
---|
796 | end |
---|
797 | |
---|
798 | // Instantiate primitive to allow this flop to be attached to multicycle |
---|
799 | // path constraint in UCF. This signal goes to PHY_WRITE and PHY_CTL_IO |
---|
800 | // datapath logic only. Because it is a multi-cycle path, it can be |
---|
801 | // clocked by either CLKDIV0 or CLK0. |
---|
802 | FDRSE u_ff_phy_init_data_sel |
---|
803 | ( |
---|
804 | .Q (phy_init_data_sel), |
---|
805 | .C (clkdiv0), |
---|
806 | .CE (1'b1), |
---|
807 | .D (phy_init_done_r1), |
---|
808 | .R (1'b0), |
---|
809 | .S (1'b0) |
---|
810 | ) /* synthesis syn_preserve=1 */ |
---|
811 | /* synthesis syn_replicate = 0 */; |
---|
812 | |
---|
813 | //synthesis translate_off |
---|
814 | always @(posedge calib_done[0]) |
---|
815 | $display ("First Stage Calibration completed at time %t", $time); |
---|
816 | |
---|
817 | always @(posedge calib_done[1]) |
---|
818 | $display ("Second Stage Calibration completed at time %t", $time); |
---|
819 | |
---|
820 | always @(posedge calib_done[2]) begin |
---|
821 | $display ("Third Stage Calibration completed at time %t", $time); |
---|
822 | end |
---|
823 | |
---|
824 | always @(posedge calib_done[3]) begin |
---|
825 | $display ("Fourth Stage Calibration completed at time %t", $time); |
---|
826 | $display ("Calibration completed at time %t", $time); |
---|
827 | end |
---|
828 | //synthesis translate_on |
---|
829 | |
---|
830 | always @(posedge clkdiv0) begin |
---|
831 | if ((init_cnt_r >= INIT_CNTR_DEEP_MEM))begin |
---|
832 | init_done_r <= 1'b1; |
---|
833 | end else |
---|
834 | init_done_r <= 1'b0; |
---|
835 | end |
---|
836 | |
---|
837 | //***************************************************************** |
---|
838 | |
---|
839 | always @(posedge clkdiv0) |
---|
840 | if (rstdiv0) begin |
---|
841 | init_state_r <= INIT_IDLE; |
---|
842 | init_state_r1 <= INIT_IDLE; |
---|
843 | init_state_r2 <= INIT_IDLE; |
---|
844 | calib_done_r <= 4'b0000; |
---|
845 | end else begin |
---|
846 | init_state_r <= init_next_state; |
---|
847 | init_state_r1 <= init_state_r; |
---|
848 | init_state_r2 <= init_state_r1; |
---|
849 | calib_done_r <= calib_done; // register for timing |
---|
850 | end |
---|
851 | |
---|
852 | always @(*) begin |
---|
853 | init_next_state = init_state_r; |
---|
854 | (* full_case, parallel_case *) case (init_state_r) |
---|
855 | INIT_IDLE: begin |
---|
856 | if (done_200us_r) begin |
---|
857 | (* parallel_case *) case (init_cnt_r) |
---|
858 | INIT_CNTR_INIT: |
---|
859 | init_next_state = INIT_CNT_200; |
---|
860 | INIT_CNTR_PRECH_1: |
---|
861 | init_next_state = INIT_PRECHARGE; |
---|
862 | INIT_CNTR_EMR2_INIT: |
---|
863 | init_next_state = INIT_LOAD_MODE; // EMR(2) |
---|
864 | INIT_CNTR_EMR3_INIT: |
---|
865 | init_next_state = INIT_LOAD_MODE; // EMR(3); |
---|
866 | INIT_CNTR_EMR_EN_DLL: |
---|
867 | init_next_state = INIT_LOAD_MODE; // EMR, enable DLL |
---|
868 | INIT_CNTR_MR_RST_DLL: |
---|
869 | init_next_state = INIT_LOAD_MODE; // MR, reset DLL |
---|
870 | INIT_CNTR_CNT_200_WAIT:begin |
---|
871 | if(DDR_TYPE == DDR3) |
---|
872 | init_next_state = INIT_ZQCL; // DDR3 |
---|
873 | else |
---|
874 | // Wait 200cc after reset DLL |
---|
875 | init_next_state = INIT_CNT_200; |
---|
876 | end |
---|
877 | INIT_CNTR_PRECH_2: |
---|
878 | init_next_state = INIT_PRECHARGE; |
---|
879 | INIT_CNTR_AR_1: |
---|
880 | init_next_state = INIT_AUTO_REFRESH; |
---|
881 | INIT_CNTR_AR_2: |
---|
882 | init_next_state = INIT_AUTO_REFRESH; |
---|
883 | INIT_CNTR_MR_ACT_DLL: |
---|
884 | init_next_state = INIT_LOAD_MODE; // MR, unreset DLL |
---|
885 | INIT_CNTR_EMR_DEF_OCD: |
---|
886 | init_next_state = INIT_LOAD_MODE; // EMR, OCD default |
---|
887 | INIT_CNTR_EMR_EXIT_OCD: |
---|
888 | init_next_state = INIT_LOAD_MODE; // EMR, enable OCD exit |
---|
889 | INIT_CNTR_DEEP_MEM: begin |
---|
890 | if ((chip_cnt_r < CS_NUM-1)) |
---|
891 | init_next_state = INIT_DEEP_MEMORY_ST; |
---|
892 | else if (cnt_200_cycle_done_r) |
---|
893 | init_next_state = INIT_DUMMY_ACTIVE; |
---|
894 | else |
---|
895 | init_next_state = INIT_IDLE; |
---|
896 | end |
---|
897 | // MIG 3.3: Remove extra precharge occurring at end of calibration |
---|
898 | // INIT_CNTR_PRECH_3: |
---|
899 | // init_next_state = INIT_PRECHARGE; |
---|
900 | INIT_CNTR_DONE: |
---|
901 | init_next_state = INIT_IDLE; |
---|
902 | default : |
---|
903 | init_next_state = INIT_IDLE; |
---|
904 | endcase |
---|
905 | end |
---|
906 | end |
---|
907 | INIT_CNT_200: |
---|
908 | init_next_state = INIT_CNT_200_WAIT; |
---|
909 | INIT_CNT_200_WAIT: |
---|
910 | if (cnt_200_cycle_done_r) |
---|
911 | init_next_state = INIT_IDLE; |
---|
912 | INIT_PRECHARGE: |
---|
913 | init_next_state = INIT_PRECHARGE_WAIT; |
---|
914 | INIT_PRECHARGE_WAIT: |
---|
915 | if (cnt_cmd_ok_r)begin |
---|
916 | if (init_done_r && (!(&calib_done_r))) |
---|
917 | init_next_state = INIT_AUTO_REFRESH; |
---|
918 | else |
---|
919 | init_next_state = INIT_IDLE; |
---|
920 | end |
---|
921 | INIT_ZQCL: |
---|
922 | init_next_state = INIT_WAIT_DLLK_ZQINIT; |
---|
923 | INIT_WAIT_DLLK_ZQINIT: |
---|
924 | if (cnt_200_cycle_done_r) |
---|
925 | init_next_state = INIT_IDLE; |
---|
926 | INIT_LOAD_MODE: |
---|
927 | init_next_state = INIT_MODE_REGISTER_WAIT; |
---|
928 | INIT_MODE_REGISTER_WAIT: |
---|
929 | if (cnt_cmd_ok_r) |
---|
930 | init_next_state = INIT_IDLE; |
---|
931 | INIT_AUTO_REFRESH: |
---|
932 | init_next_state = INIT_AUTO_REFRESH_WAIT; |
---|
933 | INIT_AUTO_REFRESH_WAIT: |
---|
934 | // MIG 2.4: Modified to issue an Auto Refresh commmand |
---|
935 | // to each chip select during various calibration stages |
---|
936 | if (auto_cnt_r < CS_NUM && init_done_r) begin |
---|
937 | if (cnt_cmd_ok_r) |
---|
938 | init_next_state = INIT_AUTO_REFRESH; |
---|
939 | end else if (cnt_cmd_ok_r)begin |
---|
940 | if (init_done_r) |
---|
941 | init_next_state = INIT_DUMMY_ACTIVE; |
---|
942 | else |
---|
943 | init_next_state = INIT_IDLE; |
---|
944 | end |
---|
945 | INIT_DEEP_MEMORY_ST: |
---|
946 | init_next_state = INIT_IDLE; |
---|
947 | // single row activate. All subsequent calibration writes and |
---|
948 | // read will take place in this row |
---|
949 | INIT_DUMMY_ACTIVE: |
---|
950 | init_next_state = INIT_DUMMY_ACTIVE_WAIT; |
---|
951 | INIT_DUMMY_ACTIVE_WAIT: |
---|
952 | if (cnt_cmd_ok_r)begin |
---|
953 | if (~calib_done_r[0]) begin |
---|
954 | // if returning to stg1 after refresh, don't need to write |
---|
955 | if (cal1_started_r) |
---|
956 | init_next_state = INIT_CAL1_READ; |
---|
957 | // if first entering stg1, need to write training pattern |
---|
958 | else |
---|
959 | init_next_state = INIT_CAL1_WRITE; |
---|
960 | end else if (~calib_done[1]) begin |
---|
961 | if (cal2_started_r) |
---|
962 | init_next_state = INIT_CAL2_READ; |
---|
963 | else |
---|
964 | init_next_state = INIT_CAL2_WRITE; |
---|
965 | end else if (~calib_done_r[2]) |
---|
966 | // Stage 3 only requires a refresh after the entire stage is |
---|
967 | // finished |
---|
968 | init_next_state = INIT_CAL3_WRITE; |
---|
969 | else begin |
---|
970 | // Stage 4 requires a refresh after every DQS group |
---|
971 | if (cal4_started_r) |
---|
972 | init_next_state = INIT_CAL4_READ; |
---|
973 | else |
---|
974 | init_next_state = INIT_CAL4_WRITE; |
---|
975 | end |
---|
976 | end |
---|
977 | // Stage 1 calibration (write and continuous read) |
---|
978 | INIT_CAL1_WRITE: |
---|
979 | if (burst_addr_r == 2'b10) |
---|
980 | init_next_state = INIT_CAL1_WRITE_READ; |
---|
981 | INIT_CAL1_WRITE_READ: |
---|
982 | if (cnt_cmd_ok_r) |
---|
983 | init_next_state = INIT_CAL1_READ; |
---|
984 | INIT_CAL1_READ: |
---|
985 | // Stage 1 requires inter-stage auto-refresh |
---|
986 | if (calib_done_r[0] || refresh_req) |
---|
987 | init_next_state = INIT_CAL1_READ_WAIT; |
---|
988 | INIT_CAL1_READ_WAIT: |
---|
989 | if (cnt_cmd_ok_r) |
---|
990 | init_next_state = INIT_CALIB_REF; |
---|
991 | // Stage 2 calibration (write and continuous read) |
---|
992 | INIT_CAL2_WRITE: |
---|
993 | if (burst_addr_r == 2'b10) |
---|
994 | init_next_state = INIT_CAL2_WRITE_READ; |
---|
995 | INIT_CAL2_WRITE_READ: |
---|
996 | if (cnt_cmd_ok_r) |
---|
997 | init_next_state = INIT_CAL2_READ; |
---|
998 | INIT_CAL2_READ: |
---|
999 | // Stage 2 requires inter-stage auto-refresh |
---|
1000 | if (calib_done_r[1] || refresh_req) |
---|
1001 | init_next_state = INIT_CAL2_READ_WAIT; |
---|
1002 | INIT_CAL2_READ_WAIT: |
---|
1003 | if (cnt_cmd_ok_r) |
---|
1004 | init_next_state = INIT_CALIB_REF; |
---|
1005 | // Stage 3 calibration (write and continuous read) |
---|
1006 | INIT_CAL3_WRITE: |
---|
1007 | if (burst_addr_r == 2'b10) |
---|
1008 | init_next_state = INIT_CAL3_WRITE_READ; |
---|
1009 | INIT_CAL3_WRITE_READ: |
---|
1010 | if (cnt_cmd_ok_r) |
---|
1011 | init_next_state = INIT_CAL3_READ; |
---|
1012 | INIT_CAL3_READ: |
---|
1013 | if (burst_addr_r == 2'b10) |
---|
1014 | init_next_state = INIT_CAL3_READ_WAIT; |
---|
1015 | INIT_CAL3_READ_WAIT: begin |
---|
1016 | if (cnt_rd_ok_r) |
---|
1017 | if (calib_done_r[2]) begin |
---|
1018 | init_next_state = INIT_CALIB_REF; |
---|
1019 | end else |
---|
1020 | init_next_state = INIT_CAL3_READ; |
---|
1021 | end |
---|
1022 | // Stage 4 calibration |
---|
1023 | INIT_CAL4_WRITE: |
---|
1024 | if (burst_addr_r == 2'b10) |
---|
1025 | init_next_state = INIT_CAL4_WRITE_READ; |
---|
1026 | INIT_CAL4_WRITE_READ: |
---|
1027 | if (cnt_cmd_ok_r) |
---|
1028 | init_next_state = INIT_CAL4_READ; |
---|
1029 | INIT_CAL4_READ: |
---|
1030 | if (burst_addr_r == 2'b10) |
---|
1031 | init_next_state = INIT_CAL4_READ_WAIT; |
---|
1032 | INIT_CAL4_READ_WAIT: begin |
---|
1033 | if (cnt_rd_ok_r) |
---|
1034 | // Stage 4 requires inter-stage auto-refresh |
---|
1035 | if (calib_done_r[3] || refresh_req) |
---|
1036 | // MIG 3.3: With removal of extra precharge, proceed to |
---|
1037 | // state CALIB_REF first to avoid incrementing init_cntr |
---|
1038 | // init_next_state = INIT_PRECHARGE; |
---|
1039 | init_next_state = INIT_CALIB_REF; |
---|
1040 | else |
---|
1041 | init_next_state = INIT_CAL4_READ; |
---|
1042 | end |
---|
1043 | INIT_CALIB_REF: |
---|
1044 | init_next_state = INIT_PRECHARGE; |
---|
1045 | endcase |
---|
1046 | end |
---|
1047 | |
---|
1048 | //*************************************************************************** |
---|
1049 | // Memory control/address |
---|
1050 | //*************************************************************************** |
---|
1051 | |
---|
1052 | always @(posedge clkdiv0) |
---|
1053 | if ((init_state_r == INIT_DUMMY_ACTIVE) || |
---|
1054 | (init_state_r == INIT_PRECHARGE) || |
---|
1055 | (init_state_r == INIT_LOAD_MODE) || |
---|
1056 | (init_state_r == INIT_AUTO_REFRESH)) begin |
---|
1057 | ddr_ras_n_r <= 1'b0; |
---|
1058 | end else begin |
---|
1059 | ddr_ras_n_r <= 1'b1; |
---|
1060 | end |
---|
1061 | |
---|
1062 | always @(posedge clkdiv0) |
---|
1063 | if ((init_state_r == INIT_LOAD_MODE) || |
---|
1064 | (init_state_r == INIT_AUTO_REFRESH) || |
---|
1065 | (cal_write_read && (burst_cnt_r == 2'b00))) begin |
---|
1066 | ddr_cas_n_r <= 1'b0; |
---|
1067 | end else begin |
---|
1068 | ddr_cas_n_r <= 1'b1; |
---|
1069 | end |
---|
1070 | |
---|
1071 | always @(posedge clkdiv0) |
---|
1072 | if ((init_state_r == INIT_LOAD_MODE) || |
---|
1073 | (init_state_r == INIT_PRECHARGE) || |
---|
1074 | (init_state_r == INIT_ZQCL) || |
---|
1075 | (cal_write && (burst_cnt_r == 2'b00)))begin |
---|
1076 | ddr_we_n_r <= 1'b0; |
---|
1077 | end else begin |
---|
1078 | ddr_we_n_r <= 1'b1; |
---|
1079 | end |
---|
1080 | |
---|
1081 | //***************************************************************** |
---|
1082 | // memory address during init |
---|
1083 | //***************************************************************** |
---|
1084 | |
---|
1085 | always @(posedge clkdiv0) begin |
---|
1086 | if ((init_state_r == INIT_PRECHARGE) |
---|
1087 | || (init_state_r == INIT_ZQCL))begin |
---|
1088 | // Precharge all - set A10 = 1 |
---|
1089 | ddr_addr_r <= {ROW_WIDTH{1'b0}}; |
---|
1090 | ddr_addr_r[10] <= 1'b1; |
---|
1091 | ddr_ba_r <= {BANK_WIDTH{1'b0}}; |
---|
1092 | end else if (init_state_r == INIT_LOAD_MODE) begin |
---|
1093 | ddr_ba_r <= {BANK_WIDTH{1'b0}}; |
---|
1094 | ddr_addr_r <= {ROW_WIDTH{1'b0}}; |
---|
1095 | case (init_cnt_r) |
---|
1096 | // EMR (2) |
---|
1097 | INIT_CNTR_EMR2_INIT: begin |
---|
1098 | ddr_ba_r[1:0] <= 2'b10; |
---|
1099 | ddr_addr_r <= {ROW_WIDTH{1'b0}}; |
---|
1100 | end |
---|
1101 | // EMR (3) |
---|
1102 | INIT_CNTR_EMR3_INIT: begin |
---|
1103 | ddr_ba_r[1:0] <= 2'b11; |
---|
1104 | if(DDR_TYPE == DDR3) |
---|
1105 | ddr_addr_r <= load_mode_reg3[ROW_WIDTH-1:0]; |
---|
1106 | else |
---|
1107 | ddr_addr_r <= {ROW_WIDTH{1'b0}}; |
---|
1108 | end |
---|
1109 | // EMR write - A0 = 0 for DLL enable |
---|
1110 | INIT_CNTR_EMR_EN_DLL: begin |
---|
1111 | ddr_ba_r[1:0] <= 2'b01; |
---|
1112 | if(DDR_TYPE == DDR3) |
---|
1113 | ddr_addr_r <= load_mode_reg1[ROW_WIDTH-1:0]; |
---|
1114 | else |
---|
1115 | ddr_addr_r <= ext_mode_reg[ROW_WIDTH-1:0]; |
---|
1116 | end |
---|
1117 | // MR write, reset DLL (A8=1) |
---|
1118 | INIT_CNTR_MR_RST_DLL: begin |
---|
1119 | if(DDR_TYPE == DDR3) |
---|
1120 | ddr_addr_r <= load_mode_reg0[ROW_WIDTH-1:0]; |
---|
1121 | else |
---|
1122 | ddr_addr_r <= load_mode_reg[ROW_WIDTH-1:0]; |
---|
1123 | ddr_ba_r[1:0] <= 2'b00; |
---|
1124 | ddr_addr_r[8] <= 1'b1; |
---|
1125 | end |
---|
1126 | // MR write, unreset DLL (A8=0) |
---|
1127 | INIT_CNTR_MR_ACT_DLL: begin |
---|
1128 | ddr_ba_r[1:0] <= 2'b00; |
---|
1129 | ddr_addr_r <= load_mode_reg[ROW_WIDTH-1:0]; |
---|
1130 | end |
---|
1131 | // EMR write, OCD default state |
---|
1132 | INIT_CNTR_EMR_DEF_OCD: begin |
---|
1133 | ddr_ba_r[1:0] <= 2'b01; |
---|
1134 | ddr_addr_r <= ext_mode_reg[ROW_WIDTH-1:0]; |
---|
1135 | ddr_addr_r[9:7] <= 3'b111; |
---|
1136 | end |
---|
1137 | // EMR write - OCD exit |
---|
1138 | INIT_CNTR_EMR_EXIT_OCD: begin |
---|
1139 | ddr_ba_r[1:0] <= 2'b01; |
---|
1140 | ddr_addr_r <= ext_mode_reg[ROW_WIDTH-1:0]; |
---|
1141 | end |
---|
1142 | default: begin |
---|
1143 | ddr_ba_r <= {BANK_WIDTH{1'bx}}; |
---|
1144 | ddr_addr_r <= {ROW_WIDTH{1'bx}}; |
---|
1145 | end |
---|
1146 | endcase |
---|
1147 | end else if (cal_write_read) begin |
---|
1148 | // when writing or reading for Stages 2-4, since training pattern is |
---|
1149 | // either 4 (stage 2) or 8 (stage 3-4) long, if BURST LEN < 8, then |
---|
1150 | // need to issue multiple bursts to read entire training pattern |
---|
1151 | ddr_addr_r[ROW_WIDTH-1:3] <= {ROW_WIDTH-4{1'b0}}; |
---|
1152 | ddr_addr_r[2:0] <= {burst_addr_r, 1'b0}; |
---|
1153 | ddr_ba_r <= {BANK_WIDTH-1{1'b0}}; |
---|
1154 | end else if (init_state_r == INIT_DUMMY_ACTIVE) begin |
---|
1155 | // all calibration writing read takes place in row 0x0 only |
---|
1156 | ddr_ba_r <= {BANK_WIDTH{1'b0}}; |
---|
1157 | ddr_addr_r <= {ROW_WIDTH{1'b0}}; |
---|
1158 | end else begin |
---|
1159 | // otherwise, cry me a river |
---|
1160 | ddr_ba_r <= {BANK_WIDTH{1'bx}}; |
---|
1161 | ddr_addr_r <= {ROW_WIDTH{1'bx}}; |
---|
1162 | end |
---|
1163 | end |
---|
1164 | |
---|
1165 | // Keep CKE asserted after initial power-on delay |
---|
1166 | always @(posedge clkdiv0) |
---|
1167 | ddr_cke_r <= {CKE_WIDTH{done_200us_r}}; |
---|
1168 | |
---|
1169 | // register commands to memory. Two clock cycle delay from state -> output |
---|
1170 | always @(posedge clk0) begin |
---|
1171 | ddr_addr_r1 <= ddr_addr_r; |
---|
1172 | ddr_ba_r1 <= ddr_ba_r; |
---|
1173 | ddr_cas_n_r1 <= ddr_cas_n_r; |
---|
1174 | ddr_ras_n_r1 <= ddr_ras_n_r; |
---|
1175 | ddr_we_n_r1 <= ddr_we_n_r; |
---|
1176 | ddr_cs_n_r1 <= ddr_cs_n_r; |
---|
1177 | end // always @ (posedge clk0) |
---|
1178 | |
---|
1179 | always @(posedge clk0) |
---|
1180 | init_state_r1_2t <= init_state_r1; |
---|
1181 | |
---|
1182 | // logic to toggle chip select. The chip_select is |
---|
1183 | // clocked of clkdiv0 and will be asserted for |
---|
1184 | // two clock cycles. |
---|
1185 | always @(posedge clk0) begin |
---|
1186 | if(rst0) |
---|
1187 | ddr_cs_disable_r <= {CS_NUM{1'b0}}; |
---|
1188 | else begin |
---|
1189 | if(| ddr_cs_disable_r) |
---|
1190 | ddr_cs_disable_r <= {CS_NUM{1'b0}}; |
---|
1191 | else begin |
---|
1192 | if (TWO_T_TIME_EN) begin |
---|
1193 | if (init_state_r1_2t == INIT_PRECHARGE && init_done_r) |
---|
1194 | ddr_cs_disable_r <= 'd3; |
---|
1195 | else |
---|
1196 | ddr_cs_disable_r[chip_cnt_r] <= ~ddr_cs_n_r1[chip_cnt_r]; |
---|
1197 | end |
---|
1198 | else begin |
---|
1199 | if (init_state_r1 == INIT_PRECHARGE && init_done_r) |
---|
1200 | ddr_cs_disable_r <= 'd3; |
---|
1201 | else |
---|
1202 | ddr_cs_disable_r[chip_cnt_r] <= ~ddr_cs_n_r[chip_cnt_r]; |
---|
1203 | end |
---|
1204 | end |
---|
1205 | end |
---|
1206 | end |
---|
1207 | |
---|
1208 | |
---|
1209 | assign phy_init_addr = ddr_addr_r; |
---|
1210 | assign phy_init_ba = ddr_ba_r; |
---|
1211 | assign phy_init_cas_n = ddr_cas_n_r; |
---|
1212 | assign phy_init_cke = ddr_cke_r; |
---|
1213 | assign phy_init_ras_n = ddr_ras_n_r; |
---|
1214 | assign phy_init_we_n = ddr_we_n_r; |
---|
1215 | assign phy_init_cs_n = (TWO_T_TIME_EN) ? |
---|
1216 | ddr_cs_n_r1 | ddr_cs_disable_r |
---|
1217 | : ddr_cs_n_r| ddr_cs_disable_r; |
---|
1218 | |
---|
1219 | endmodule |
---|