1 //==============================================================================
2 // File: $URL: svn+ssh://repositorypub@repository.eecs.berkeley.edu/public/Projects/GateLib/branches/dev/Firmware/DRAM/Hardware/DDR2SDRAM/DDR2SDRAM.v $
3 // Version: $Revision: 16878 $
4 // Author: Greg Gibeling (http://gdgib.gotdns.com/~gdgib/)
5 // Copyright: Copyright 2005-2008 UC Berkeley
6 //==============================================================================
8 //==============================================================================
10 //==============================================================================
11 // Copyright (c) 2005-2008, Regents of the University of California
12 // All rights reserved.
14 // Redistribution and use in source and binary forms, with or without modification,
15 // are permitted provided that the following conditions are met:
17 // - Redistributions of source code must retain the above copyright notice,
18 // this list of conditions and the following disclaimer.
19 // - Redistributions in binary form must reproduce the above copyright
20 // notice, this list of conditions and the following disclaimer
21 // in the documentation and/or other materials provided with the
23 // - Neither the name of the University of California, Berkeley nor the
24 // names of its contributors may be used to endorse or promote
25 // products derived from this software without specific prior
26 // written permission.
28 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
29 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
30 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
31 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
32 // ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
33 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
34 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
35 // ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 //==============================================================================
40 //==============================================================================
42 //==============================================================================
44 //==============================================================================
46 //------------------------------------------------------------------------------
48 // Based On: svn+ssh://repositorypub@repository.eecs.berkeley.edu/public/Projects/GateLib/trunk/Firmware/DRAM/DRAM.v
49 // Author: <a href="http://gdgib.gotdns.com/~gdgib/">Greg Gibeling</a>
50 // Version: $Revision: 16878 $
51 //------------------------------------------------------------------------------
53 //------------------------------------------------------------------
54 // Clock & Reset Inputs
55 //------------------------------------------------------------------
62 //------------------------------------------------------------------
64 //------------------------------------------------------------------
66 //------------------------------------------------------------------
69 //------------------------------------------------------------------
71 //------------------------------------------------------------------
73 //------------------------------------------------------------------
81 //------------------------------------------------------------------
83 //------------------------------------------------------------------
84 // Data Input (Write) Interface
85 //------------------------------------------------------------------
93 //------------------------------------------------------------------
95 //------------------------------------------------------------------
96 // Data Output (Read) Interface
97 //------------------------------------------------------------------
103 DataOutErrorCorrected,
106 //------------------------------------------------------------------
108 //------------------------------------------------------------------
109 // DDR2 Memory Interface
110 //------------------------------------------------------------------
125 //------------------------------------------------------------------
127 //--------------------------------------------------------------------------
129 //--------------------------------------------------------------------------
130 parameter UWidth = 8, // This will almost ALWAYS be 8
131 BAWidth = 2, // Setup the addressing line for the ML505@256MB, Address components are listed from most to least significant
134 DWidth = 128, // 128b SDR internal transfers
135 BurstLen = 2, // 256b total burst, 2 words DWidth words at SDR, or 4 external words at DDR
138 Board = 0, // 0 - ML505, 1 - BEE3A, 2 - BEE3B
139 MultiClock = 0, // 0 - Use Clock & Reset for everything, 1 - Use the individual FIFO clock and resets
141 //--------------------------------------------------------------------------
143 //--------------------------------------------------------------------------
145 //--------------------------------------------------------------------------
147 localparam UCount = DWidth / UWidth,
148 MWidth = (EnableECC || (EnableMask == 0)) ? 0 : UCount, // 128b/8 = 16b per mask means per-byte masking
149 UAWidth = `log2(UCount-1), // Unused lower address bits, the -1 is to get a proper log2
150 XAWidth = `max(RAWidth, CAWidth),
151 TAWidth = CAWidth + RAWidth + BAWidth,
152 AWidth = TAWidth + UAWidth - 1, // Note that the components are in order according to where in the address they appear, the -1 is to account for DDR
153 CommandMask = 7'b0000011, // Read & Write only
154 ECheck = EnableECC ? 2 : 0,
155 ECorrect = EnableECC ? 1 : 0,
157 COMMAND_Write = 3'b000,
158 COMMAND_Read = 3'b001,
159 COMMAND_Flush = 3'b010,
160 COMMAND_Refresh = 3'b011,
161 COMMAND_AutoRefresh = 3'b100,
162 COMMAND_PowerDown = 3'b101,
163 COMMAND_PowerUp = 3'b110,
164 EHWidth = `max(`log2(ECheck), 1),
165 ERWidth = `max(`log2(ECheck), 1);
167 //--------------------------------------------------------------------------
169 //--------------------------------------------------------------------------
170 // Per-Board Settings
171 //--------------------------------------------------------------------------
172 // SHOULD BE A CASE BASED ON "Board"
173 localparam CKE_WIDTH = Board ? 1 : 1,
174 CLK_WIDTH = Board ? 1 : 2,
175 CS_NUM = Board ? 1 : 1,
176 CS_WIDTH = Board ? 1 : 1,
177 DM_WIDTH = EnableMask ? (UCount / 2) : 0,
178 DQ_WIDTH = (DWidth / 2) + (EnableECC ? (DWidth / 8) : 0),
179 DQ_PER_DQS = Board ? 4 : 8,
180 DQS_WIDTH = DQ_WIDTH/DQ_PER_DQS,
181 ODT_WIDTH = Board ? 1 : 1,
182 ADDITIVE_LAT = AdditiveLatency,
183 CAS_LAT = Board ? 4 : 4,
184 MULTI_BANK_EN = Board ? 1 : 1,
185 TWO_T_TIME_EN = Board ? 0 : 1,
186 ODT_TYPE = Board ? 3 : 1,
187 REDUCE_DRV = Board ? 1 : 0,
188 TREFI_NS = Board ? 7800 : 7800,
189 TRAS = Board ? 40000 : 40000,
190 TRCD = Board ? 15000 : 15000,
191 TRFC = Board ? 127500 : 105000,
192 TRP = Board ? 15000 : 15000,
193 TRTP = Board ? 7500 : 7500,
194 TWR = Board ? 15000 : 15000,
195 TWTR = Board ? 10000 : 7500,
196 HIGH_PERFORMANCE_MODE = "TRUE",
197 DQS_IO_COL = Board ? ((Board == 2) ? 36'b010000000000000000000101101010101010 : 36'b010000000000000000000101101010101010) : 16'b0000000000000000,
198 DQ_IO_MS = Board ? ((Board == 2) ? 72'b11011110_10011100_11001001_00111000_01101110_01100101_10101100_01011010_10011010 : 72'b11011010_10110001_01110101_10110100_10101100_01100101_11010100_11101000_10100011) : 64'b01110101_00111101_00001111_00011110_00101110_11000011_11000001_10111100,
199 CLK_PERIOD = Board ? 3750 : 3750;
200 //--------------------------------------------------------------------------
202 //--------------------------------------------------------------------------
203 // Internal Constants
204 //--------------------------------------------------------------------------
206 localparam SIM_ONLY = 1;
208 localparam SIM_ONLY = 0;
210 //--------------------------------------------------------------------------
212 //--------------------------------------------------------------------------
213 // Clock & Reset Inputs
214 //--------------------------------------------------------------------------
215 input Clock, ClockD2, ClockP90, Reset, Locked;
217 //--------------------------------------------------------------------------
219 //--------------------------------------------------------------------------
221 //--------------------------------------------------------------------------
224 //--------------------------------------------------------------------------
226 //--------------------------------------------------------------------------
228 //--------------------------------------------------------------------------
229 input CommandClock, CommandReset;
231 input [AWidth-1:0] CommandAddress;
232 input [CWidth-1:0] Command;
235 //--------------------------------------------------------------------------
237 //--------------------------------------------------------------------------
238 // Data Input (Write) Interface
239 //--------------------------------------------------------------------------
240 input DataInClock, DataInReset;
242 input [DWidth-1:0] DataIn;
243 input [MWidth-1:0] DataInMask;
246 //--------------------------------------------------------------------------
248 //--------------------------------------------------------------------------
249 // Data Output (Read) Interface
250 //--------------------------------------------------------------------------
251 input DataOutClock, DataOutReset;
253 output [DWidth-1:0] DataOut;
254 output [EHWidth-1:0] DataOutErrorChecked;
255 output [ERWidth-1:0] DataOutErrorCorrected;
258 //--------------------------------------------------------------------------
260 //--------------------------------------------------------------------------
261 // DDR2 Memory Interface
262 //--------------------------------------------------------------------------
263 inout [DQ_WIDTH-1:0] DDR2_DQ;
264 output [XAWidth-1:0] DDR2_A;
265 output [BAWidth-1:0] DDR2_BA;
269 output [CS_WIDTH-1:0] DDR2_CS0_B;
272 output [DM_WIDTH-1:0] DDR2_DM;
273 inout [DQS_WIDTH-1:0] DDR2_DQS_P;
274 inout [DQS_WIDTH-1:0] DDR2_DQS_N;
275 output [CLK_WIDTH-1:0] DDR2_CLK_P;
276 output [CLK_WIDTH-1:0] DDR2_CLK_N;
277 //--------------------------------------------------------------------------
279 //--------------------------------------------------------------------------
281 //--------------------------------------------------------------------------
282 wire app_af_afull, app_wdf_afull, rd_data_valid;
283 wire [1:0] rd_ecc_error;
286 //--------------------------------------------------------------------------
288 //--------------------------------------------------------------------------
290 //--------------------------------------------------------------------------
291 assign CommandReady = ~app_af_afull & Gate;
292 assign DataInReady = ~app_wdf_afull & Gate;
293 assign DataOutValid = rd_data_valid & Gate;
295 assign DataOutErrorChecked = EnableECC ? rd_ecc_error[1] : {EHWidth{1'b0}};
296 assign DataOutErrorCorrected = EnableECC ? rd_ecc_error[0] : {ERWidth{1'b0}};
298 assign PoweredUp = 1'b1;
299 assign Gate = Initialized & ~Reset;
300 //--------------------------------------------------------------------------
302 //--------------------------------------------------------------------------
304 //--------------------------------------------------------------------------
306 initial if ((Board < 0) || (Board > 2)) $display("ERROR: Board type ", Board, " is not supported 0 - ML505, 1 - BEE3A, 2 - BEE3B are valid!");
307 initial if (Board == 0) begin
308 if (DWidth != 128) $display("ERROR: ML505 supports only 128b DWidth!");
309 if (UWidth != 8) $display("ERROR: ML505 supports only 8b UWidth!");
310 if (EnableMask == 0) $display("ERROR: ML505 requires mask!");
311 if (EnableECC != 0) $display("ERROR: ML505 does not support ECC!");
313 initial if ((Board == 1) || (Board == 2)) begin
314 if (EnableECC != 0) begin
315 if (DWidth != 128) $display("ERROR: BEE3 supports only 128b DWidth when ECC is enabled!");
317 if ((DWidth != 144) && (DWidth != 128)) $display("ERROR: BEE3 supports 128 or 144 DWidth when ECC is disabled!");
319 if (UWidth != 8) $display("ERROR: BEE3 supports only 8b UWidth!");
320 if (EnableMask != 0) $display("ERROR: BEE3 does not support mask!");
322 initial if ((DQ_WIDTH % UWidth) != 0) $display("ERROR: External data transfer width must be a multiple of the unit width: ", DQ_WIDTH, " is not a multiple of ", UWidth);
323 initial if ((BurstLen != 2) && (BurstLen != 4)) $display("ERROR: Interface burst length must be 2 or 4 (4 or 8 at DDR) not: ", BurstLen);
324 initial if (TAWidth > 31) $display("ERROR: MIG2.3 core only supports up to 31 internal address bits (TAWidth > 31 is invalid)!");
325 always @ (posedge Clock) begin
326 if (CommandReady & CommandValid & ~((CommandMask >> Command) & 1'b1)) $display("ERROR: Unsupported memory command: ", Command);
329 //--------------------------------------------------------------------------
331 //--------------------------------------------------------------------------
332 // MIG 2.x DDR2 SDRAM Controller
333 //--------------------------------------------------------------------------
334 ddr2_sdram #( .BANK_WIDTH( BAWidth), // # of memory bank addr bits
335 .CKE_WIDTH( CKE_WIDTH), // # of memory clock enable outputs
336 .CLK_WIDTH( CLK_WIDTH), // # of clock outputs
337 .COL_WIDTH( CAWidth), // # of memory column bits
338 .CS_NUM( CS_NUM), // # of separate memory chip selects
339 .CS_WIDTH( CS_WIDTH), // # of total memory chip selects
340 .CS_BITS( `log2(CS_NUM)), // set to log2(CS_NUM) (rounded up)
341 .DM_WIDTH( DM_WIDTH), // # of data mask bits
342 .DQ_WIDTH( DQ_WIDTH), // # of data width
343 .DQ_PER_DQS( DQ_PER_DQS), // # of DQ data bits per strobe
344 .DQS_WIDTH( DQS_WIDTH), // # of DQS strobes
345 .DQ_BITS( `log2(DQ_WIDTH-1)), // set to log2(DQS_WIDTH*DQ_PER_DQS)
346 .DQS_BITS( `log2((DQ_WIDTH/DQ_PER_DQS)-1)), // set to log2(DQS_WIDTH)
347 .ODT_WIDTH( ODT_WIDTH), // # of memory on-die term enables
348 .ROW_WIDTH( RAWidth), // # of memory row and # of addr bits
349 .ADDITIVE_LAT( ADDITIVE_LAT), // additive write latency
350 .BURST_LEN( BurstLen * 2), // burst length (in double words)
351 .BURST_TYPE( 0), // burst type (=0 seq; =1 interleaved), totally useless thanks to the DDR to SDR conversion
352 .CAS_LAT( CAS_LAT), // CAS latency
353 .ECC_ENABLE( EnableECC), // enable ECC (=1 enable)
354 .APPDATA_WIDTH( DWidth), // # of usr read/write data bus bits
355 .MULTI_BANK_EN( MULTI_BANK_EN), // Keeps multiple banks open. (= 1 enable)
356 .TWO_T_TIME_EN( TWO_T_TIME_EN), // 2t timing for unbuffered dimms
357 .ODT_TYPE( ODT_TYPE), // ODT (=0(none),=1(75),=2(150),=3(50))
358 .REDUCE_DRV( REDUCE_DRV), // reduced strength mem I/O (=1 yes)
359 .REG_ENABLE( 0), // registered addr/ctrl (=1 yes), cannot be changed without rerunning MIG/CoreGen
360 .TREFI_NS( TREFI_NS), // auto refresh interval (ns)
361 .TRAS( TRAS), // active->precharge delay
362 .TRCD( TRCD), // active->read/write delay
363 .TRFC( TRFC), // refresh->refresh, refresh->active delay
364 .TRP( TRP), // precharge->command delay
365 .TRTP( TRTP), // read->precharge delay
366 .TWR( TWR), // used to determine write->precharge
367 .TWTR( TWTR), // write->read delay
368 .HIGH_PERFORMANCE_MODE(HIGH_PERFORMANCE_MODE), // TRUE, the IODELAY performance mode is set to high. FALSE, the IODELAY performance mode is set to low.
369 .SIM_ONLY( SIM_ONLY), // = 1 to skip SDRAM power up delay
370 .DEBUG_EN( 0), // Enable debug signals/controls
371 .DQS_IO_COL( DQS_IO_COL), // I/O column location of DQS groups (=0, left; =1 center, =2 right)
372 .DQ_IO_MS( DQ_IO_MS), // Master/Slave location of DQ I/O (=0 slave)
373 .CLK_PERIOD( CLK_PERIOD), // Core/Memory clock period (in ps)
374 .RST_ACT_LOW( 0), // =1 for active low reset, =0 for active high
375 .EN_SYN( MultiClock ? "FALSE" : "TRUE"))
376 mig20( .ddr2_dq( DDR2_DQ),
379 .ddr2_ras_n( DDR2_RAS_B),
380 .ddr2_cas_n( DDR2_CAS_B),
381 .ddr2_we_n( DDR2_WE_B),
382 .ddr2_cs_n( DDR2_CS0_B),
383 .ddr2_odt( DDR2_ODT),
384 .ddr2_cke( DDR2_CKE),
386 .ddr2_dqs( DDR2_DQS_P),
387 .ddr2_dqs_n( DDR2_DQS_N),
388 .ddr2_ck( DDR2_CLK_P),
389 .ddr2_ck_n( DDR2_CLK_N),
392 .phy_init_done( Initialized),
401 .af_clk( MultiClock ? CommandClock : Clock),
402 .af_rst( MultiClock ? CommandReset : Reset),
403 .app_af_afull( app_af_afull),
404 .app_af_wren( CommandValid & (~|Command[2:1]) & CommandReady & Gate),
405 .app_af_addr( {{((30 - AWidth) + UAWidth){1'b0}}, CommandAddress[AWidth-1:UAWidth], 1'b0}), // The final 1'b0 is to compensate for the DDR to SDR conversion
406 .app_af_cmd( {2'b00, Command[0]}),
408 .wb_clk( MultiClock ? DataInClock : Clock),
409 .wb_rst( MultiClock ? DataInReset : Reset),
410 .app_wdf_afull( app_wdf_afull),
411 .app_wdf_wren( DataInValid & DataInReady & Gate),
412 .app_wdf_data( DataIn),
413 .app_wdf_mask_data( DataInMask),
415 .rb_clk( MultiClock ? DataOutClock : Clock),
416 .rb_rst( MultiClock ? DataOutReset : Reset),
417 .rd_data_valid( rd_data_valid),
418 .rd_ecc_error( rd_ecc_error),
419 .rd_data_rden( DataOutReady & Gate),
420 .rd_data_fifo_out( DataOut),
422 //--------------------------------------------------------------------------
424 //------------------------------------------------------------------------------