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