bba6f40693428c0d4971fc84ee79bc6d01d168be
[fleet.git] / src / edu / berkeley / fleet / fpga / greg / DDR2SDRAM.v
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 //==============================================================================
7
8 //==============================================================================
9 //      Section:        License
10 //==============================================================================
11 //      Copyright (c) 2005-2008, Regents of the University of California
12 //      All rights reserved.
13 //
14 //      Redistribution and use in source and binary forms, with or without modification,
15 //      are permitted provided that the following conditions are met:
16 //
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
22 //                      distribution.
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.
27 //
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 //==============================================================================
39
40 //==============================================================================
41 //      Includes
42 //==============================================================================
43 `include "Const.v"
44 //==============================================================================
45
46 //------------------------------------------------------------------------------
47 //      Module:         DDR2SDRAM
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 //------------------------------------------------------------------------------
52 module  DDR2SDRAM(
53                         //------------------------------------------------------------------
54                         //      Clock & Reset Inputs
55                         //------------------------------------------------------------------
56                         Clock,
57                         ClockD2,
58                         ClockP90,
59                         Reset,
60                         Locked,
61                         ClockF200,
62                         //------------------------------------------------------------------
63         
64                         //------------------------------------------------------------------
65                         //      Status Outputs
66                         //------------------------------------------------------------------
67                         Initialized,
68                         PoweredUp,
69                         //------------------------------------------------------------------
70         
71                         //------------------------------------------------------------------
72                         //      Command Interface
73                         //------------------------------------------------------------------
74                         CommandClock,
75                         CommandReset,
76                         
77                         CommandAddress,
78                         Command,
79                         CommandValid,
80                         CommandReady,
81                         //------------------------------------------------------------------
82         
83                         //------------------------------------------------------------------
84                         //      Data Input (Write) Interface
85                         //------------------------------------------------------------------
86                         DataInClock,
87                         DataInReset,
88                         
89                         DataIn,
90                         DataInMask,
91                         DataInValid,
92                         DataInReady,
93                         //------------------------------------------------------------------
94         
95                         //------------------------------------------------------------------
96                         //      Data Output (Read) Interface
97                         //------------------------------------------------------------------
98                         DataOutClock,
99                         DataOutReset,
100                         
101                         DataOut,
102                         DataOutErrorChecked,
103                         DataOutErrorCorrected,
104                         DataOutValid,
105                         DataOutReady,
106                         //------------------------------------------------------------------
107                         
108                         //------------------------------------------------------------------
109                         //      DDR2 Memory Interface
110                         //------------------------------------------------------------------
111                         DDR2_DQ,
112                         DDR2_A,
113                         DDR2_BA,
114                         DDR2_RAS_B,
115                         DDR2_CAS_B,
116                         DDR2_WE_B,
117                         DDR2_CS0_B,
118                         DDR2_ODT,
119                         DDR2_CKE,
120                         DDR2_DM,
121                         DDR2_DQS_P,
122                         DDR2_DQS_N,
123                         DDR2_CLK_P,
124                         DDR2_CLK_N
125                         //------------------------------------------------------------------
126         );
127         //--------------------------------------------------------------------------
128         //      Parameters
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
132                                                         RAWidth =                               13,
133                                                         CAWidth =                               10,                                                     
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
136                                                         EnableMask =                    1,
137                                                         EnableECC =                             0,
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
140                                                         AdditiveLatency =               0;
141         //--------------------------------------------------------------------------
142         
143         //--------------------------------------------------------------------------
144         //      Fixed Constants
145         //--------------------------------------------------------------------------
146         `ifdef MACROSAFE
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,
156                                                         CWidth =                                3,
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);
166         `endif
167         //--------------------------------------------------------------------------
168         
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         //--------------------------------------------------------------------------
201         
202         //--------------------------------------------------------------------------
203         //      Internal Constants
204         //--------------------------------------------------------------------------
205         `ifdef MODELSIM
206         localparam                              SIM_ONLY =                              1;
207         `else
208         localparam                              SIM_ONLY =                              0;
209         `endif
210         //--------------------------------------------------------------------------
211         
212         //--------------------------------------------------------------------------
213         //      Clock & Reset Inputs
214         //--------------------------------------------------------------------------
215         input                                   Clock, ClockD2, ClockP90, Reset, Locked;
216         input                                   ClockF200;
217         //--------------------------------------------------------------------------
218         
219         //--------------------------------------------------------------------------
220         //      Status Outputs
221         //--------------------------------------------------------------------------
222         output                                  Initialized;
223         output                                  PoweredUp;
224         //--------------------------------------------------------------------------
225         
226         //--------------------------------------------------------------------------
227         //      Command Interface
228         //--------------------------------------------------------------------------
229         input                                   CommandClock, CommandReset;
230         
231         input   [AWidth-1:0]    CommandAddress;
232         input   [CWidth-1:0]    Command; 
233         input                                   CommandValid;
234         output                                  CommandReady;
235         //--------------------------------------------------------------------------
236         
237         //--------------------------------------------------------------------------
238         //      Data Input (Write) Interface
239         //--------------------------------------------------------------------------
240         input                                   DataInClock, DataInReset;
241         
242         input   [DWidth-1:0]    DataIn;
243         input   [MWidth-1:0]    DataInMask;
244         input                                   DataInValid;
245         output                                  DataInReady;
246         //--------------------------------------------------------------------------
247         
248         //--------------------------------------------------------------------------
249         //      Data Output (Read) Interface
250         //--------------------------------------------------------------------------
251         input                                   DataOutClock, DataOutReset;
252         
253         output  [DWidth-1:0]    DataOut;
254         output  [EHWidth-1:0]   DataOutErrorChecked;
255         output  [ERWidth-1:0]   DataOutErrorCorrected;
256         output                                  DataOutValid;
257         input                                   DataOutReady;
258         //--------------------------------------------------------------------------
259         
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;
266         output                                  DDR2_RAS_B;
267         output                                  DDR2_CAS_B;
268         output                                  DDR2_WE_B;
269         output  [CS_WIDTH-1:0]  DDR2_CS0_B;
270         output                                  DDR2_ODT;
271         output                                  DDR2_CKE;
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         //--------------------------------------------------------------------------
278         
279         //--------------------------------------------------------------------------
280         //      Internal Wires
281         //--------------------------------------------------------------------------
282         wire                                    app_af_afull, app_wdf_afull, rd_data_valid;
283         wire    [1:0]                   rd_ecc_error;
284         
285         wire                                    Gate;
286         //--------------------------------------------------------------------------
287         
288         //--------------------------------------------------------------------------
289         //      Assign Statements
290         //--------------------------------------------------------------------------
291         assign  CommandReady =                                                  ~app_af_afull & Gate;
292         assign  DataInReady =                                                   ~app_wdf_afull & Gate;
293         assign  DataOutValid =                                                  rd_data_valid & Gate;
294         
295         assign  DataOutErrorChecked =                                   EnableECC ? rd_ecc_error[1] : {EHWidth{1'b0}};
296         assign  DataOutErrorCorrected =                                 EnableECC ? rd_ecc_error[0] : {ERWidth{1'b0}};
297         
298         assign  PoweredUp =                                                             1'b1;
299         assign  Gate =                                                                  Initialized & ~Reset;
300         //--------------------------------------------------------------------------
301         
302         //--------------------------------------------------------------------------
303         //      Checks
304         //--------------------------------------------------------------------------
305         `ifdef MODELSIM
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!");
312                 end
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!");
316                         end else begin
317                                 if ((DWidth != 144) && (DWidth != 128)) $display("ERROR: BEE3 supports 128 or 144 DWidth when ECC is disabled!");
318                         end
319                         if (UWidth != 8) $display("ERROR: BEE3 supports only 8b UWidth!");
320                         if (EnableMask != 0) $display("ERROR: BEE3 does not support mask!");
321                 end
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);
327                 end
328         `endif
329         //--------------------------------------------------------------------------
330         
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),
377                                                                 .ddr2_a(                        DDR2_A),
378                                                                 .ddr2_ba(                       DDR2_BA),
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),
385                                                                 .ddr2_dm(                       DDR2_DM),
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),
390
391                                                                 .sys_rst_n(                     Reset),
392                                                                 .phy_init_done(         Initialized),
393                                                                 .dcm_lock(                      Locked),
394                                                                 .rst0_tb(                       ),
395                                                                 .clk0_tb(                       ),
396                                                                 .clk0(                          Clock),
397                                                                 .clk90(                         ClockP90),
398                                                                 .clk200(                        ClockF200),
399                                                                 .clkdiv0(                       ClockD2),
400
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]}),
407                                                                 
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),                                                                                                            
414                                                                 
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),
421                                                                 .rb_full(                       ));
422         //--------------------------------------------------------------------------
423 endmodule       
424 //------------------------------------------------------------------------------