OpenCores
URL https://opencores.org/ocsvn/wbddr3/wbddr3/trunk

Subversion Repositories wbddr3

[/] [wbddr3/] [trunk/] [rtl/] [wbddrsdram.v] - Blame information for rev 9

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 dgisselq
////////////////////////////////////////////////////////////////////////////////
2
//
3
// Filename:    wbddrsdram.v
4
//
5
// Project:     OpenArty, an entirely open SoC based upon the Arty platform
6
//
7
// Purpose:     
8
//
9 9 dgisselq
/*
10
Stall logic:
11
        1. First clock sets r_* variables.
12
        2. Second clock sets need_* variables.  If need_open, need_close, or
13
                need_refresh are true, that should also set the o_wb_stall
14
                variable.  Well also move r_* info to s_* (think s=stall)
15
        3. If stalled, the next command comes from s_*.  Otherwise, from r_*.
16
        4. Bus FIFO fills from s_*
17
//
18
//
19
        For every transaction, one of 4 possibilities:
20
        1. Wait for refresh to complete
21
        2. Wait for precharge and activate to complete
22
        3. Wait for activate to complete
23
        4. Issue RW cmd
24
                5. Wait for bus transaction to complete
25
                6. ACK
26
*/
27 2 dgisselq
// Creator:     Dan Gisselquist, Ph.D.
28
//              Gisselquist Technology, LLC
29
//
30
////////////////////////////////////////////////////////////////////////////////
31
//
32
// Copyright (C) 2015-2016, Gisselquist Technology, LLC
33
//
34
// This program is free software (firmware): you can redistribute it and/or
35
// modify it under the terms of  the GNU General Public License as published
36
// by the Free Software Foundation, either version 3 of the License, or (at
37
// your option) any later version.
38
//
39
// This program is distributed in the hope that it will be useful, but WITHOUT
40
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
41
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
42
// for more details.
43
//
44
// You should have received a copy of the GNU General Public License along
45
// with this program.  (It's in the $(ROOT)/doc directory, run make with no
46
// target there if the PDF file isn't present.)  If not, see
47
// <http://www.gnu.org/licenses/> for a copy.
48
//
49
// License:     GPL, v3, as defined and found on www.gnu.org,
50
//              http://www.gnu.org/licenses/gpl.html
51
//
52
//
53
////////////////////////////////////////////////////////////////////////////////
54
//
55
//
56
 
57
// Possible commands to the DDR3 memory.  These consist of settings for the
58
// bits: o_wb_cs_n, o_wb_ras_n, o_wb_cas_n, and o_wb_we_n, respectively.
59
`define DDR_MRSET       4'b0000
60
`define DDR_REFRESH     4'b0001
61
`define DDR_PRECHARGE   4'b0010
62
`define DDR_ACTIVATE    4'b0011
63
`define DDR_WRITE       4'b0100
64
`define DDR_READ        4'b0101
65 4 dgisselq
`define DDR_ZQS         4'b0110
66 2 dgisselq
`define DDR_NOOP        4'b0111
67
//`define       DDR_DESELECT    4'b1???
68
//
69
// In this controller, 24-bit commands tend to be passed around.  These 
70
// 'commands' are bit fields.  Here we specify the bits associated with
71
// the bit fields.
72 5 dgisselq
`define DDR_RSTDONE     24      // End the reset sequence?
73
`define DDR_RSTTIMER    23      // Does this reset command take multiple clocks?
74
`define DDR_RSTBIT      22      // Value to place on reset_n
75
`define DDR_CKEBIT      21      // Should this reset command set CKE?
76 7 dgisselq
//
77
// Refresh command bit fields
78
`define DDR_NEEDREFRESH 23
79
`define DDR_RFTIMER     22
80
`define DDR_RFBEGIN     21
81
//
82 5 dgisselq
`define DDR_CMDLEN      21
83
`define DDR_CSBIT       20
84
`define DDR_RASBIT      19
85
`define DDR_CASBIT      18
86
`define DDR_WEBIT       17
87
`define DDR_NOPTIMER    16      // Steal this from BA bits
88 2 dgisselq
`define DDR_BABITS      3       // BABITS are really from 18:16, they are 3 bits
89 3 dgisselq
`define DDR_ADDR_BITS   14
90 7 dgisselq
//
91
`define BUSREG  7
92
`define BUSNOW  8
93 2 dgisselq
 
94 3 dgisselq
module  wbddrsdram(i_clk, i_reset,
95 2 dgisselq
                i_wb_cyc, i_wb_stb, i_wb_we, i_wb_addr, i_wb_data,
96 3 dgisselq
                        o_wb_ack, o_wb_stall, o_wb_data,
97 2 dgisselq
                o_ddr_reset_n, o_ddr_cke,
98
                o_ddr_cs_n, o_ddr_ras_n, o_ddr_cas_n, o_ddr_we_n,
99 4 dgisselq
                o_ddr_dqs, o_ddr_dm, o_ddr_odt, o_ddr_bus_oe,
100
                o_ddr_addr, o_ddr_ba, o_ddr_data, i_ddr_data,
101
                o_cmd_accepted);
102 3 dgisselq
        parameter       CKREFI4 = 13'd6240, // 4 * 7.8us at 200 MHz clock
103 7 dgisselq
                        CKRFC = 320,
104 4 dgisselq
                        CKXPR = CKRFC+5+2; // Clocks per tXPR timeout
105 3 dgisselq
        input                   i_clk, i_reset;
106 2 dgisselq
        // Wishbone inputs
107
        input                   i_wb_cyc, i_wb_stb, i_wb_we;
108
        input           [25:0]   i_wb_addr;
109
        input           [31:0]   i_wb_data;
110
        // Wishbone outputs
111
        output  reg             o_wb_ack;
112
        output  reg             o_wb_stall;
113
        output  reg     [31:0]   o_wb_data;
114
        // DDR3 RAM Controller
115 3 dgisselq
        output  wire            o_ddr_reset_n, o_ddr_cke;
116 2 dgisselq
        // Control outputs
117
        output  reg             o_ddr_cs_n, o_ddr_ras_n, o_ddr_cas_n,o_ddr_we_n;
118
        // DQS outputs:set to 3'b010 when data is active, 3'b100 (i.e. 2'bzz) ow
119 3 dgisselq
        output  wire            o_ddr_dqs;
120 4 dgisselq
        output  reg             o_ddr_dm, o_ddr_odt, o_ddr_bus_oe;
121 2 dgisselq
        // Address outputs
122
        output  reg     [13:0]   o_ddr_addr;
123
        output  reg     [2:0]    o_ddr_ba;
124
        // And the data inputs and outputs
125
        output  reg     [31:0]   o_ddr_data;
126 7 dgisselq
        input           [31:0]   i_ddr_data;
127 4 dgisselq
        // And just for the test bench
128
        output  reg             o_cmd_accepted;
129 2 dgisselq
 
130 4 dgisselq
        always @(posedge i_clk)
131
                o_cmd_accepted <= (i_wb_stb)&&(~o_wb_stall);
132
 
133 3 dgisselq
        reg             drive_dqs;
134
 
135
        // The pending transaction
136
        reg     [31:0]   r_data;
137
        reg             r_pending, r_we;
138
        reg     [25:0]   r_addr;
139 5 dgisselq
        reg     [13:0]   r_row;
140 3 dgisselq
        reg     [2:0]    r_bank;
141
        reg     [9:0]    r_col;
142
        reg     [1:0]    r_sub;
143
        reg             r_move; // It was accepted, and can move to next stage
144
 
145 9 dgisselq
        // The pending transaction, one further into the pipeline.  This is
146
        // the stage where the read/write command is actually given to the
147
        // interface if we haven't stalled.
148
        reg     [31:0]   s_data;
149
        reg             s_pending, s_we, s_match;
150
        reg     [25:0]   s_addr;
151
        reg     [13:0]   s_row, s_nxt_row;
152
        reg     [2:0]    s_bank, s_nxt_bank;
153
        reg     [9:0]    s_col;
154
        reg     [1:0]    s_sub;
155
 
156 3 dgisselq
        // Can the pending transaction be satisfied with the current (ongoing)
157
        // transaction?
158 9 dgisselq
        reg             m_move, m_match, m_pending, m_we;
159 3 dgisselq
        reg     [25:0]   m_addr;
160 5 dgisselq
        reg     [13:0]   m_row;
161 3 dgisselq
        reg     [2:0]    m_bank;
162
        reg     [9:0]    m_col;
163
        reg     [1:0]    m_sub;
164
 
165
        // Can we preload the next bank?
166 5 dgisselq
        reg     [13:0]   r_nxt_row;
167 3 dgisselq
        reg     [2:0]    r_nxt_bank;
168 6 dgisselq
 
169
        reg     need_close_bank, need_close_this_bank,
170
                        last_close_bank, maybe_close_next_bank,
171
                        last_maybe_close,
172
                need_open_bank, last_open_bank, maybe_open_next_bank,
173
                        last_maybe_open,
174
                valid_bank, last_valid_bank;
175
        reg     [(`DDR_CMDLEN-1):0]      close_bank_cmd, activate_bank_cmd,
176
                                        maybe_close_cmd, maybe_open_cmd, rw_cmd;
177 9 dgisselq
        reg     [1:0]    rw_sub;
178
        reg             rw_we;
179 7 dgisselq
 
180
        wire    w_this_closing_bank, w_this_opening_bank,
181
                w_this_maybe_close, w_this_maybe_open,
182 9 dgisselq
                w_this_rw_move;
183 7 dgisselq
        reg     last_closing_bank, last_opening_bank;
184 2 dgisselq
//
185
// tWTR = 7.5
186
// tRRD = 7.5
187
// tREFI= 7.8
188
// tFAW = 45
189
// tRTP = 7.5
190
// tCKE = 5.625
191
// tRFC = 160
192
// tRP  = 13.5
193
// tRAS = 36
194
// tRCD = 13.5
195
//
196
// RESET:
197
//      1. Hold o_reset_n = 1'b0; for 200 us, or 40,000 clocks (65536 perhaps?)
198
//              Hold cke low during this time as well
199
//              The clock should be free running into the chip during this time
200
//              Leave command in NOOP state: {cs,ras,cas,we} = 4'h7;
201
//              ODT must be held low
202
//      2. Hold cke low for another 500us, or 100,000 clocks
203
//      3. Raise CKE, continue outputting a NOOP for
204
//              tXPR, tDLLk, and tZQInit
205
//      4. Load MRS2, wait tMRD
206
//      4. Load MRS3, wait tMRD
207
//      4. Load MRS1, wait tMOD
208
// Before using the SDRAM, we'll need to program at least 3 of the mode
209
//      registers, if not all 4. 
210
//   tMOD clocks are required to program the mode registers, during which
211
//      time the RAM must be idle.
212
//
213
// NOOP: CS low, RAS, CAS, and WE high
214
 
215
//
216
// Reset logic should be simple, and is given as follows:
217
// note that it depends upon a ROM memory, reset_mem, and an address into that
218
// memory: reset_address.  Each memory location provides either a "command" to
219
// the DDR3 SDRAM, or a timer to wait until the next command.  Further, the
220
// timer commands indicate whether or not the command during the timer is to
221
// be set to idle, or whether the command is instead left as it was.
222 9 dgisselq
        reg             reset_override, reset_ztimer, maintenance_override;
223 6 dgisselq
        reg     [4:0]    reset_address;
224 9 dgisselq
        reg     [(`DDR_CMDLEN-1):0]      reset_cmd, cmd, refresh_cmd,
225
                                        maintenance_cmd;
226 5 dgisselq
        reg     [24:0]   reset_instruction;
227 3 dgisselq
        reg     [16:0]   reset_timer;
228
        initial reset_override = 1'b1;
229 6 dgisselq
        initial reset_address  = 5'h0;
230 2 dgisselq
        always @(posedge i_clk)
231
                if (i_reset)
232
                begin
233
                        reset_override <= 1'b1;
234 5 dgisselq
                        reset_cmd <= { `DDR_NOOP, reset_instruction[16:0]};
235
                end else if (reset_ztimer)
236
                begin
237
                        if (reset_instruction[`DDR_RSTDONE])
238
                                reset_override <= 1'b0;
239
                        reset_cmd <= reset_instruction[20:0];
240
                end
241 2 dgisselq
        always @(posedge i_clk)
242
                if (i_reset)
243
                        o_ddr_cke <= 1'b0;
244 3 dgisselq
                else if ((reset_override)&&(reset_ztimer))
245 2 dgisselq
                        o_ddr_cke <= reset_instruction[`DDR_CKEBIT];
246
 
247 4 dgisselq
        initial reset_ztimer = 1'b0;    // Is the timer zero?
248 5 dgisselq
        initial reset_timer = 17'h02;
249 2 dgisselq
        always @(posedge i_clk)
250
                if (i_reset)
251
                begin
252
                        reset_ztimer <= 1'b0;
253 5 dgisselq
                        reset_timer <= 17'd2;
254 2 dgisselq
                end else if (!reset_ztimer)
255
                begin
256
                        reset_ztimer <= (reset_timer == 17'h01);
257
                        reset_timer <= reset_timer - 17'h01;
258
                end else if (reset_instruction[`DDR_RSTTIMER])
259
                begin
260
                        reset_ztimer <= 1'b0;
261
                        reset_timer <= reset_instruction[16:0];
262
                end
263
 
264 5 dgisselq
        wire    [16:0]   w_ckXPR = CKXPR, w_ckRST = 4, w_ckRP = 3,
265 4 dgisselq
                        w_ckRFC = CKRFC;
266 2 dgisselq
        always @(posedge i_clk)
267 4 dgisselq
                if (i_reset)
268 5 dgisselq
                        reset_instruction <= { 4'h4, `DDR_NOOP, 17'd40_000 };
269
                else if (reset_ztimer) case(reset_address) // RSTDONE, TIMER, CKE, ??
270 4 dgisselq
                // 1. Reset asserted (active low) for 200 us. (@200MHz)
271 6 dgisselq
                5'h0: reset_instruction <= { 4'h4, `DDR_NOOP, 17'd40_000 };
272 4 dgisselq
                // 2. Reset de-asserted, wait 500 us before asserting CKE
273 6 dgisselq
                5'h1: reset_instruction <= { 4'h6, `DDR_NOOP, 17'd100_000 };
274 4 dgisselq
                // 3. Assert CKE, wait minimum of Reset CKE Exit time
275 6 dgisselq
                5'h2: reset_instruction <= { 4'h7, `DDR_NOOP, w_ckXPR };
276 4 dgisselq
                // 4. Look MR2.  (1CK, no TIMER)
277 6 dgisselq
                5'h3: reset_instruction <= { 4'h3, `DDR_MRSET, 3'h2,
278 5 dgisselq
                        3'h0, 2'b00, 1'b0, 1'b0, 1'b1, 3'b0, 3'b0 }; // MRS2
279 4 dgisselq
                // 3. Wait 4 clocks (tMRD)
280 6 dgisselq
                5'h4: reset_instruction <= { 4'h7, `DDR_NOOP, 17'h02 };
281 4 dgisselq
                // 5. Set MR1
282 6 dgisselq
                5'h5: reset_instruction <= { 4'h3, `DDR_MRSET, 3'h1,
283 5 dgisselq
                        1'h0, // Reserved for Future Use (RFU)
284 4 dgisselq
                        1'b0, // Qoff - output buffer enabled
285
                        1'b1, // TDQS ... enabled
286
                        1'b0, // RFU
287
                        1'b0, // High order bit, Rtt_Nom (3'b011)
288
                        1'b0, // RFU
289
                        //
290
                        1'b0, // Disable write-leveling
291
                        1'b1, // Mid order bit of Rtt_Nom
292
                        1'b0, // High order bit of Output Drvr Impedence Ctrl
293
                        2'b0, // Additive latency = 0
294
                        1'b1, // Low order bit of Rtt_Nom
295
                        1'b1, // DIC set to 2'b01
296
                        1'b1 }; // MRS1, DLL enable
297
                // 7. Wait another 4 clocks
298 6 dgisselq
                5'h6: reset_instruction <= { 4'h7, `DDR_NOOP, 17'h02 };
299 4 dgisselq
                // 8. Send MRS0
300 6 dgisselq
                5'h7: reset_instruction <= { 4'h3, `DDR_MRSET, 3'h0,
301 5 dgisselq
                        1'b0, // Reserved for future use
302 4 dgisselq
                        1'b0, // PPD control, (slow exit(DLL off))
303
                        3'b1, // Write recovery for auto precharge
304
                        1'b0, // DLL Reset (No)
305
                        //
306
                        1'b0, // TM mode normal
307
                        3'b01, // High 3-bits, CAS latency (=4'b0010 = 4'd5)
308
                        1'b0, // Read burst type = nibble sequential
309
                        1'b0, // Low bit of cas latency
310
                        2'b0 }; // Burst length = 8 (Fixed)
311
                // 9. Wait tMOD, is max(12 clocks, 15ns)
312 6 dgisselq
                5'h8: reset_instruction <= { 4'h7, `DDR_NOOP, 17'h0a };
313 4 dgisselq
                // 10. Issue a ZQCL command to start ZQ calibration, A10 is high
314 6 dgisselq
                5'h9: reset_instruction <= { 4'h3, `DDR_ZQS, 6'h0, 1'b1, 10'h0};
315 4 dgisselq
                //11.Wait for both tDLLK and tZQinit completed, both are 512 cks
316 6 dgisselq
                5'ha: reset_instruction <= { 4'h7, `DDR_NOOP, 17'd512 };
317 4 dgisselq
                // 12. Precharge all command
318 6 dgisselq
                5'hb: reset_instruction <= { 4'h3, `DDR_PRECHARGE, 6'h0, 1'b1, 10'h0 };
319 4 dgisselq
                // 13. Wait for the precharge to complete
320 6 dgisselq
                5'hc: reset_instruction <= { 4'h7, `DDR_NOOP, w_ckRP };
321 4 dgisselq
                // 14. A single Auto Refresh commands
322 6 dgisselq
                5'hd: reset_instruction <= { 4'h3, `DDR_REFRESH, 17'h00 };
323 4 dgisselq
                // 15. Wait for the auto refresh to complete
324 6 dgisselq
                5'he: reset_instruction <= { 4'h7, `DDR_NOOP, w_ckRFC };
325 4 dgisselq
                // Two Auto Refresh commands
326 2 dgisselq
                default:
327 5 dgisselq
                        reset_instruction <={4'hb, `DDR_NOOP, 17'd00_000 };
328 2 dgisselq
                endcase
329
                // reset_instruction <= reset_mem[reset_address];
330
 
331 6 dgisselq
        initial reset_address = 5'h0;
332 2 dgisselq
        always @(posedge i_clk)
333
                if (i_reset)
334 6 dgisselq
                        reset_address <= 5'h1;
335
                else if ((reset_ztimer)&&(reset_override))
336
                        reset_address <= reset_address + 5'h1;
337 2 dgisselq
//
338
// initial reset_mem =
339
//       0.     !DONE, TIMER,RESET_N=0, CKE=0, CMD = NOOP, TIMER = 200us ( 40,000)
340
//       1.     !DONE, TIMER,RESET_N=1, CKE=0, CMD = NOOP, TIMER = 500us (100,000)
341
//       2.     !DONE, TIMER,RESET_N=1, CKE=1, CMD = NOOP, TIMER = (Look me up)
342
//       3.     !DONE,!TIMER,RESET_N=1, CKE=1, CMD = MODE, MRS
343
//       4.     !DONE,!TIMER,RESET_N=1, CKE=1, CMD = NOOP, TIMER = tMRS
344
//       5.     !DONE,!TIMER,RESET_N=1, CKE=1, CMD = MODE, MRS3
345
//       6.     !DONE,!TIMER,RESET_N=1, CKE=1, CMD = NOOP, TIMER = tMRS
346
//       7.     !DONE,!TIMER,RESET_N=1, CKE=1, CMD = MODE, MRS1
347
//       8.     !DONE,!TIMER,RESET_N=1, CKE=1, CMD = NOOP, TIMER = tMRS
348
//       9.     !DONE,!TIMER,RESET_N=1, CKE=1, CMD = MODE, MRS1
349
//      10.     !DONE,!TIMER,RESET_N=1, CKE=1, CMD = NOOP, TIMER = tMOD
350
//      11.     !DONE,!TIMER,RESET_N=1, CKE=1, (Pre-charge all)
351
//      12.     !DONE,!TIMER,RESET_N=1, CKE=1, (wait)
352
//      13.     !DONE,!TIMER,RESET_N=1, CKE=1, (Auto-refresh)
353
//      14.     !DONE,!TIMER,RESET_N=1, CKE=1, (Auto-refresh)
354
//      15.     !DONE,!TIMER,RESET_N=1, CKE=1, (wait)
355
 
356
 
357
//
358
//
359
// Let's keep track of any open banks.  There are 8 of them to keep track of.
360
//
361
//      A precharge requires 3 clocks at 200MHz to complete, 2 clocks at 100MHz.
362
//      
363
//
364
//
365 3 dgisselq
        reg     need_refresh;
366 2 dgisselq
 
367 3 dgisselq
        wire    w_precharge_all;
368
        reg     banks_are_closing, all_banks_closed;
369 6 dgisselq
        reg     [3:0]    bank_status     [0:7];
370
        reg     [13:0]   bank_address    [0:7];
371
 
372 2 dgisselq
        always @(posedge i_clk)
373
        begin
374 6 dgisselq
                bank_status[0] <= { bank_status[0][2:0], bank_status[0][0] };
375
                bank_status[1] <= { bank_status[1][2:0], bank_status[1][0] };
376
                bank_status[2] <= { bank_status[2][2:0], bank_status[2][0] };
377
                bank_status[3] <= { bank_status[3][2:0], bank_status[3][0] };
378
                bank_status[4] <= { bank_status[4][2:0], bank_status[4][0] };
379
                bank_status[5] <= { bank_status[5][2:0], bank_status[5][0] };
380
                bank_status[6] <= { bank_status[6][2:0], bank_status[6][0] };
381
                bank_status[7] <= { bank_status[7][2:0], bank_status[7][0] };
382
                all_banks_closed <= (bank_status[0][2:0] == 3'b00)
383
                                        &&(bank_status[1][2:0] == 3'b00)
384
                                        &&(bank_status[2][2:0] == 3'b00)
385
                                        &&(bank_status[3][2:0] == 3'b00)
386
                                        &&(bank_status[4][2:0] == 3'b00)
387
                                        &&(bank_status[5][2:0] == 3'b00)
388
                                        &&(bank_status[6][2:0] == 3'b00)
389
                                        &&(bank_status[7][2:0] == 3'b00);
390 7 dgisselq
                if (reset_override)
391 2 dgisselq
                begin
392 6 dgisselq
                        bank_status[0][0] <= 1'b0;
393
                        bank_status[1][0] <= 1'b0;
394
                        bank_status[2][0] <= 1'b0;
395
                        bank_status[3][0] <= 1'b0;
396
                        bank_status[4][0] <= 1'b0;
397
                        bank_status[5][0] <= 1'b0;
398
                        bank_status[6][0] <= 1'b0;
399
                        bank_status[7][0] <= 1'b0;
400 2 dgisselq
                        banks_are_closing <= 1'b1;
401 7 dgisselq
                end else if ((need_refresh)||(w_precharge_all))
402
                begin
403
                        bank_status[0][0] <= 1'b0;
404
                        bank_status[1][0] <= 1'b0;
405
                        bank_status[2][0] <= 1'b0;
406
                        bank_status[3][0] <= 1'b0;
407
                        bank_status[4][0] <= 1'b0;
408
                        bank_status[5][0] <= 1'b0;
409
                        bank_status[6][0] <= 1'b0;
410
                        bank_status[7][0] <= 1'b0;
411
                        banks_are_closing <= 1'b1;
412 2 dgisselq
                end else if (need_close_bank)
413
                begin
414 6 dgisselq
                        bank_status[close_bank_cmd[16:14]]
415 8 dgisselq
                                <= { bank_status[close_bank_cmd[16:14]][2:0], 1'b0 };
416 6 dgisselq
                        // bank_status[close_bank_cmd[16:14]][0] <= 1'b0;
417 2 dgisselq
                end else if (need_open_bank)
418
                begin
419 6 dgisselq
                        bank_status[activate_bank_cmd[16:14]]
420
                                <= { bank_status[activate_bank_cmd[16:14]][2:0], 1'b1 };
421
                        // bank_status[activate_bank_cmd[16:14]][0] <= 1'b1;
422 2 dgisselq
                        all_banks_closed <= 1'b0;
423
                        banks_are_closing <= 1'b0;
424 6 dgisselq
                end else if ((valid_bank)&&(!r_move))
425
                        ;
426
                else if (maybe_close_next_bank)
427
                begin
428
                        bank_status[maybe_close_cmd[16:14]]
429 8 dgisselq
                                <= { bank_status[maybe_close_cmd[16:14]][2:0], 1'b0 };
430 6 dgisselq
                end else if (maybe_open_next_bank)
431
                begin
432
                        bank_status[maybe_open_cmd[16:14]]
433
                                <= { bank_status[maybe_open_cmd[16:14]][2:0], 1'b1 };
434
                        // bank_status[activate_bank_cmd[16:14]][0] <= 1'b1;
435
                        all_banks_closed <= 1'b0;
436
                        banks_are_closing <= 1'b0;
437 2 dgisselq
                end
438
        end
439
 
440
        always @(posedge i_clk)
441 3 dgisselq
                // if (cmd[22:19] == `DDR_ACTIVATE)
442 8 dgisselq
                if (w_this_opening_bank)
443 5 dgisselq
                        bank_address[activate_bank_cmd[16:14]]
444
                                <= activate_bank_cmd[13:0];
445 8 dgisselq
                else if (!w_this_maybe_open)
446
                        bank_address[maybe_open_cmd[16:14]]
447
                                <= maybe_open_cmd[13:0];
448 2 dgisselq
 
449
//
450
//
451
// Okay, let's investigate when we need to do a refresh.  Our plan will be to
452
// do 4 refreshes every tREFI*4 seconds.  tREFI = 7.8us, but its a parameter
453
// in the number of clocks so that we can handle both 100MHz and 200MHz clocks.
454
//
455
// Note that 160ns are needed between refresh commands (JEDEC, p172), or
456
// 320 clocks @200MHz, or equivalently 160 clocks @100MHz.  Thus to issue 4
457
// of these refresh cycles will require 4*320=1280 clocks@200 MHz.  After this
458
// time, no more refreshes will be needed for 6240 clocks.
459
//
460
// Let's think this through:
461
//      REFRESH_COST = (n*(320)+24)/(n*1560)
462
// 
463
//
464
//
465 7 dgisselq
        reg             refresh_ztimer;
466
        reg     [16:0]   refresh_counter;
467
        reg     [3:0]    refresh_addr;
468
        reg     [23:0]   refresh_instruction;
469 2 dgisselq
        always @(posedge i_clk)
470 7 dgisselq
                if (reset_override)
471
                        refresh_addr <= 4'hf;
472
                else if (refresh_ztimer)
473
                        refresh_addr <= refresh_addr + 1;
474
                else if (refresh_instruction[`DDR_RFBEGIN])
475
                        refresh_addr <= 4'h0;
476 6 dgisselq
 
477 2 dgisselq
        always @(posedge i_clk)
478 7 dgisselq
                if (reset_override)
479
                begin
480
                        refresh_ztimer <= 1'b1;
481
                        refresh_counter <= 17'd0;
482
                end else if (!refresh_ztimer)
483
                begin
484
                        refresh_ztimer <= (refresh_counter == 17'h1);
485
                        refresh_counter <= (refresh_counter - 17'h1);
486
                end else if (refresh_instruction[`DDR_RFTIMER])
487
                begin
488
                        refresh_ztimer <= 1'b0;
489
                        refresh_counter <= refresh_instruction[16:0];
490
                end
491 2 dgisselq
 
492 7 dgisselq
        wire    [16:0]   w_ckREFIn, w_ckREFRst;
493
        assign  w_ckREFIn[ 12: 0] = CKREFI4-5*CKRFC-2-10;
494
        assign  w_ckREFIn[ 16:13] = 4'h0;
495 8 dgisselq
        assign  w_ckREFRst[12: 0] = CKRFC-2-12;
496 7 dgisselq
        assign  w_ckREFRst[16:13] = 4'h0;
497
 
498 2 dgisselq
        always @(posedge i_clk)
499 7 dgisselq
                if (reset_override)
500
                        refresh_instruction <= { 3'h0, `DDR_NOOP, w_ckREFIn };
501
                else if (refresh_ztimer)
502
                        refresh_cmd <= refresh_instruction[20:0];
503 2 dgisselq
        always @(posedge i_clk)
504 7 dgisselq
                if (reset_override)
505
                        need_refresh <= 1'b0;
506
                else if (refresh_ztimer)
507
                        need_refresh <= refresh_instruction[`DDR_NEEDREFRESH];
508 2 dgisselq
 
509
        always @(posedge i_clk)
510 7 dgisselq
        if (refresh_ztimer)
511
                case(refresh_addr)//NEED-RFC, HAVE-TIMER, 
512
                4'h0: refresh_instruction <= { 3'h2, `DDR_NOOP, w_ckREFIn };
513
                // 17'd10 = time to complete write, plus write recovery time
514
                //              minus two (cause we can't count zero or one)
515
                //      = WL+4+tWR-2 = 10
516
                //      = 5+4+3-2 = 10
517
                4'h1: refresh_instruction <= { 3'h6, `DDR_NOOP, 17'd10 };
518
                4'h2: refresh_instruction <= { 3'h4, `DDR_PRECHARGE, 17'h0400 };
519
                4'h3: refresh_instruction <= { 3'h6, `DDR_NOOP, 17'd2 };
520
                4'h4: refresh_instruction <= { 3'h4, `DDR_REFRESH, 17'h00 };
521
                4'h5: refresh_instruction <= { 3'h6, `DDR_NOOP, w_ckRFC };
522
                4'h6: refresh_instruction <= { 3'h4, `DDR_REFRESH, 17'h00 };
523
                4'h7: refresh_instruction <= { 3'h6, `DDR_NOOP, w_ckRFC };
524
                4'h8: refresh_instruction <= { 3'h4, `DDR_REFRESH, 17'h00 };
525
                4'h9: refresh_instruction <= { 3'h6, `DDR_NOOP, w_ckRFC };
526
                4'ha: refresh_instruction <= { 3'h4, `DDR_REFRESH, 17'h00 };
527
                4'hb: refresh_instruction <= { 3'h6, `DDR_NOOP, w_ckRFC };
528 8 dgisselq
                4'hc: refresh_instruction <= { 3'h2, `DDR_NOOP, w_ckREFRst };
529 7 dgisselq
                default:
530
                        refresh_instruction <= { 3'h1, `DDR_NOOP, 17'h00 };
531
                endcase
532 2 dgisselq
 
533
 
534
//
535
//
536
//      Let's track: when will our bus be active?  When will we be reading or
537
//      writing?
538
//
539
//
540 7 dgisselq
        reg     [`BUSNOW:0]      bus_active, bus_read, bus_new;
541
        reg     [1:0]    bus_subaddr     [`BUSNOW:0];
542 3 dgisselq
        initial bus_active = 0;
543 2 dgisselq
        always @(posedge i_clk)
544
        begin
545 7 dgisselq
                bus_active[`BUSNOW:0] <= { bus_active[(`BUSNOW-1):0], 1'b0 };
546
                bus_read[`BUSNOW:0]   <= { bus_read[(`BUSNOW-1):0], 1'b0 }; // Drive the d-bus?
547 9 dgisselq
                // Is this a new command?  i.e., the start of a transaction?
548
                bus_new[`BUSNOW:0]   <= { bus_new[(`BUSNOW-1):0], 1'b0 };
549 3 dgisselq
                //bus_mask[8:0] <= { bus_mask[7:0], 1'b1 }; // Write this value?
550 2 dgisselq
                bus_subaddr[8]  <= bus_subaddr[7];
551
                bus_subaddr[7]  <= bus_subaddr[6];
552
                bus_subaddr[6]  <= bus_subaddr[5];
553
                bus_subaddr[5]  <= bus_subaddr[4];
554
                bus_subaddr[4]  <= bus_subaddr[3];
555
                bus_subaddr[3]  <= bus_subaddr[2];
556
                bus_subaddr[2]  <= bus_subaddr[1];
557
                bus_subaddr[1]  <= bus_subaddr[0];
558
                bus_subaddr[0]  <= 2'h3;
559 7 dgisselq
                if (w_this_rw_move)
560 2 dgisselq
                begin
561
                        bus_active[3:0]<= 4'hf; // Once per clock
562
                        bus_read[3:0]  <= 4'hf; // These will be reads
563
                        bus_subaddr[3] <= 2'h0;
564
                        bus_subaddr[2] <= 2'h1;
565
                        bus_subaddr[1] <= 2'h2;
566 9 dgisselq
                        bus_new[{ 2'b0, rw_sub }] <= 1'b1;
567 4 dgisselq
 
568 9 dgisselq
                        bus_read[3:0] <= (rw_we)? 4'h0:4'hf;
569 2 dgisselq
                end
570
        end
571
 
572
        always @(posedge i_clk)
573 7 dgisselq
                drive_dqs <= (~bus_read[`BUSREG])&&(|bus_active[`BUSREG]);
574 2 dgisselq
 
575
//
576
//
577
// Now, let's see, can we issue a read command?
578
//
579
//
580 9 dgisselq
        wire    w_s_match;
581
        assign  w_s_match = (s_pending)&&(r_pending)&&(r_we == s_we)
582
                                &&(r_row == s_row)&&(r_bank == s_bank)
583
                                &&(r_col == s_col)
584
                                &&(r_sub > s_sub);
585
        reg     pipe_stall;
586 2 dgisselq
        always @(posedge i_clk)
587
        begin
588 9 dgisselq
                r_pending <= (i_wb_stb)&&(~o_wb_stall)
589
                                ||(r_pending)&&(pipe_stall);
590
                if (~pipe_stall)
591
                        s_pending <= r_pending;
592
                if (~pipe_stall)
593 2 dgisselq
                begin
594 9 dgisselq
                        pipe_stall <= (r_pending)&&(((!w_r_valid)||(valid_bank))&&(!w_s_match));
595
                        o_wb_stall <= (r_pending)&&(((!w_r_valid)||(valid_bank))&&(!w_s_match));
596
                end else begin // if (pipe_stall)
597
                        pipe_stall <= (s_pending)&&((!w_s_valid)||(valid_bank)||(r_move)||(last_valid_bank));
598
                        o_wb_stall <= (s_pending)&&((!w_s_valid)||(valid_bank)||(r_move)||(last_valid_bank));
599
                end
600
                if (need_refresh)
601 2 dgisselq
                        o_wb_stall <= 1'b1;
602
 
603 9 dgisselq
                if (~pipe_stall)
604 2 dgisselq
                begin
605
                        r_we   <= i_wb_we;
606
                        r_addr <= i_wb_addr;
607
                        r_data <= i_wb_data;
608 5 dgisselq
                        r_row  <= i_wb_addr[25:12];
609
                        r_bank <= i_wb_addr[11:9];
610
                        r_col  <= { i_wb_addr[8:2], 3'b000 }; // 9:2
611 2 dgisselq
                        r_sub  <= i_wb_addr[1:0];
612
 
613
                        // pre-emptive work
614 6 dgisselq
                        r_nxt_row  <= (i_wb_addr[11:9]==3'h7)?i_wb_addr[25:12]+14'h1:i_wb_addr[25:12];
615 5 dgisselq
                        r_nxt_bank <= i_wb_addr[11:9]+3'h1;
616 2 dgisselq
                end
617 9 dgisselq
 
618
                if (~pipe_stall)
619
                begin
620
                        // Moving one down the pipeline
621
                        s_we   <= r_we;
622
                        s_addr <= r_addr;
623
                        s_data <= r_data;
624
                        s_row  <= r_row;
625
                        s_bank <= r_bank;
626
                        s_col  <= r_col;
627
                        s_sub  <= r_sub;
628
 
629
                        // pre-emptive work
630
                        s_nxt_row  <= r_nxt_row;
631
                        s_nxt_bank <= r_nxt_bank;
632
 
633
                        s_match <= w_s_match;
634
                end
635 2 dgisselq
        end
636
 
637 9 dgisselq
        wire    w_need_close_this_bank, w_need_open_bank,
638
                w_r_valid, w_s_valid;
639 6 dgisselq
        assign  w_need_close_this_bank = (r_pending)&&(bank_status[r_bank][0])
640 9 dgisselq
                        &&(r_row != bank_address[r_bank])
641
                        ||(pipe_stall)&&(s_pending)&&(bank_status[s_bank][0])
642
                                &&(s_row != bank_address[s_bank]);
643
        assign  w_need_open_bank = (r_pending)&&(bank_status[r_bank][1:0]==2'b00)
644
                        ||(pipe_stall)&&(s_pending)&&(bank_status[s_bank][1:0]==2'b00);
645
        assign  w_r_valid = (!need_refresh)&&(r_pending)
646
                        &&(bank_status[r_bank][3])
647
                        &&(bank_address[r_bank]==r_row)
648
                        &&(!bus_active[0]);
649
        assign  w_s_valid = (!need_refresh)&&(s_pending)
650
                        &&(bank_status[s_bank][3])
651
                        &&(bank_address[s_bank]==s_row)
652
                        &&(!bus_active[0]);
653 3 dgisselq
 
654 2 dgisselq
        always @(posedge i_clk)
655
        begin
656 6 dgisselq
                need_close_bank <= (w_need_close_this_bank)
657
                                &&(!w_this_closing_bank)&&(!last_closing_bank);
658 2 dgisselq
 
659
                maybe_close_next_bank <= (r_pending)
660 6 dgisselq
                        &&(bank_status[r_nxt_bank][0])
661 2 dgisselq
                        &&(r_nxt_row != bank_address[r_nxt_bank])
662 6 dgisselq
                        &&(!w_this_maybe_close)&&(!last_maybe_close);
663 2 dgisselq
 
664 6 dgisselq
                close_bank_cmd <= { `DDR_PRECHARGE, r_bank, r_row[13:11], 1'b0, r_row[9:0] };
665
                maybe_close_cmd <= { `DDR_PRECHARGE, r_nxt_bank, r_nxt_row[13:11], 1'b0, r_nxt_row[9:0] };
666 2 dgisselq
 
667
 
668 6 dgisselq
                need_open_bank <= (w_need_open_bank)
669
                                &&(!w_this_opening_bank)&&(!last_opening_bank);
670
                last_open_bank <= (w_this_opening_bank);
671 2 dgisselq
 
672
                maybe_open_next_bank <= (r_pending)
673 6 dgisselq
                        &&(bank_status[r_bank][0] == 1'b1)
674
                        &&(bank_status[r_nxt_bank][1:0] == 2'b00)
675
                        &&(!w_this_maybe_open)&&(!last_maybe_open);
676
                last_maybe_open <= (w_this_maybe_open);
677 2 dgisselq
 
678 6 dgisselq
                activate_bank_cmd<= { `DDR_ACTIVATE,  r_bank,     r_row[13:0] };
679
                maybe_open_cmd <= { `DDR_ACTIVATE,r_nxt_bank, r_nxt_row[13:0] };
680 2 dgisselq
 
681
 
682
 
683 9 dgisselq
                valid_bank <= ((w_r_valid)||(pipe_stall)&&(w_s_valid))
684
                                &&(!last_valid_bank)&&(!r_move);
685 6 dgisselq
                last_valid_bank <= r_move;
686 2 dgisselq
 
687 9 dgisselq
                if ((s_pending)&&(pipe_stall))
688
                        rw_cmd[`DDR_CSBIT:`DDR_WEBIT] <= (s_we)?`DDR_WRITE:`DDR_READ;
689
                else if (r_pending)
690
                        rw_cmd[`DDR_CSBIT:`DDR_WEBIT] <= (r_we)?`DDR_WRITE:`DDR_READ;
691
                else
692
                        rw_cmd[`DDR_CSBIT:`DDR_WEBIT] <= `DDR_NOOP;
693
                if ((s_pending)&&(pipe_stall))
694
                        rw_cmd[`DDR_WEBIT-1:0] <= { s_bank, 3'h0, 1'b0, s_col };
695
                else
696
                        rw_cmd[`DDR_WEBIT-1:0] <= { r_bank, 3'h0, 1'b0, r_col };
697
                if ((s_pending)&&(pipe_stall))
698
                        rw_sub <= 2'b11 - s_sub;
699
                else
700
                        rw_sub <= 2'b11 - r_sub;
701
                if ((s_pending)&&(pipe_stall))
702
                        rw_we <= s_we;
703
                else
704
                        rw_we <= r_we;
705
 
706 2 dgisselq
        end
707
 
708
//
709
//
710
// Okay, let's look at the last assignment in our chain.  It should look
711
// something like:
712
        always @(posedge i_clk)
713 4 dgisselq
                if (i_reset)
714
                        o_ddr_reset_n <= 1'b0;
715
                else if (reset_ztimer)
716
                        o_ddr_reset_n <= reset_instruction[`DDR_RSTBIT];
717 2 dgisselq
        always @(posedge i_clk)
718 4 dgisselq
                if (i_reset)
719
                        o_ddr_cke <= 1'b0;
720
                else if (reset_ztimer)
721
                        o_ddr_cke <= reset_instruction[`DDR_CKEBIT];
722 6 dgisselq
 
723 9 dgisselq
        always @(posedge i_clk)
724
                if (i_reset)
725
                        maintenance_override <= 1'b1;
726
                else
727
                        maintenance_override <= (reset_override)||(need_refresh);
728 7 dgisselq
 
729 9 dgisselq
        initial maintenance_cmd = { `DDR_NOOP, 17'h00 };
730
        always @(posedge i_clk)
731
                if (i_reset)
732
                        maintenance_cmd <= { `DDR_NOOP, 17'h00 };
733
                else
734
                        maintenance_cmd <= (reset_override)?reset_cmd:refresh_cmd;
735
 
736
        assign  w_this_closing_bank = (!maintenance_override)
737 6 dgisselq
                                &&(need_close_bank);
738 9 dgisselq
        assign  w_this_opening_bank = (!maintenance_override)
739 6 dgisselq
                                &&(!need_close_bank)&&(need_open_bank);
740 9 dgisselq
        assign  w_this_rw_move = (!maintenance_override)
741 7 dgisselq
                                &&(!need_close_bank)&&(!need_open_bank)
742
                                &&(valid_bank)&&(!r_move);
743 9 dgisselq
        assign  w_this_maybe_close = (!maintenance_override)
744 6 dgisselq
                                &&(!need_close_bank)&&(!need_open_bank)
745
                                &&((!valid_bank)||(r_move))
746
                                &&(maybe_close_next_bank);
747 9 dgisselq
        assign  w_this_maybe_open = (!maintenance_override)
748 6 dgisselq
                                &&(!need_close_bank)&&(!need_open_bank)
749
                                &&((!valid_bank)||(r_move))
750
                                &&(!maybe_close_next_bank)
751
                                &&(maybe_open_next_bank);
752 2 dgisselq
        always @(posedge i_clk)
753
        begin
754 6 dgisselq
                last_opening_bank <= 1'b0;
755
                last_closing_bank <= 1'b0;
756
                last_maybe_open   <= 1'b0;
757
                last_maybe_close  <= 1'b0;
758 2 dgisselq
                r_move <= 1'b0;
759 9 dgisselq
                if (maintenance_override) // Command from either reset or
760
                        cmd <= maintenance_cmd; // refresh logic
761
                else if (need_close_bank)
762 2 dgisselq
                begin
763
                        cmd <= close_bank_cmd;
764 6 dgisselq
                        last_closing_bank <= 1'b1;
765
                end else if (need_open_bank)
766
                begin
767 2 dgisselq
                        cmd <= activate_bank_cmd;
768 6 dgisselq
                        last_opening_bank <= 1'b1;
769
                end else if ((valid_bank)&&(!r_move))
770 2 dgisselq
                begin
771
                        cmd <= rw_cmd;
772
                        r_move <= 1'b1;
773 6 dgisselq
                end else if (maybe_close_next_bank)
774
                begin
775
                        cmd <= maybe_close_cmd;
776
                        last_maybe_close <= 1'b1;
777
                end else if (maybe_open_next_bank)
778
                begin
779
                        cmd <= maybe_open_cmd;
780
                        last_maybe_open <= 1'b1;
781 2 dgisselq
                end else
782 4 dgisselq
                        cmd <= { `DDR_NOOP, rw_cmd[(`DDR_WEBIT-1):0] };
783 2 dgisselq
        end
784
 
785 7 dgisselq
`define LGFIFOLN        4
786
`define FIFOLEN         16
787
        reg     [(`LGFIFOLN-1):0]        bus_fifo_head, bus_fifo_tail;
788
        reg     [31:0]   bus_fifo_data   [0:(`FIFOLEN-1)];
789
        reg     [1:0]    bus_fifo_sub    [0:(`FIFOLEN-1)];
790
        reg             bus_fifo_new    [0:(`FIFOLEN-1)];
791
        reg             pre_ack;
792 3 dgisselq
 
793 7 dgisselq
        // The bus R/W FIFO
794
        wire    w_bus_fifo_read_next_transaction;
795 9 dgisselq
        assign  w_bus_fifo_read_next_transaction =
796
                (bus_fifo_sub[bus_fifo_tail]==bus_subaddr[`BUSREG])
797
                &&(bus_fifo_tail != bus_fifo_head)
798
                &&(bus_active[`BUSREG])
799
                &&(bus_new[`BUSREG] == bus_fifo_new[bus_fifo_tail]);
800 7 dgisselq
        always @(posedge i_clk)
801
        begin
802
                pre_ack <= 1'b0;
803
                o_ddr_dm <= 1'b0;
804
                if ((i_reset)||(reset_override))
805
                begin
806
                        bus_fifo_head <= 4'h0;
807
                        bus_fifo_tail <= 4'h0;
808
                        o_ddr_dm <= 1'b0;
809
                end else begin
810 9 dgisselq
                        if ((w_this_rw_move)||((s_pending)&&(s_match)&&(!pipe_stall)))
811 7 dgisselq
                                bus_fifo_head <= bus_fifo_head + 4'h1;
812
 
813
                        o_ddr_dm <= (bus_active[`BUSREG])&&(!bus_read[`BUSREG]);
814
                        if (w_bus_fifo_read_next_transaction)
815
                        begin
816
                                bus_fifo_tail <= bus_fifo_tail + 4'h1;
817
                                pre_ack <= 1'b1;
818
                                o_ddr_dm <= 1'b0;
819
                        end
820
                end
821 9 dgisselq
                bus_fifo_data[bus_fifo_head] <= s_data;
822
                bus_fifo_sub[bus_fifo_head] <= s_sub;
823 7 dgisselq
                bus_fifo_new[bus_fifo_head] <= w_this_rw_move;
824
        end
825
 
826
 
827 3 dgisselq
        assign  o_ddr_cs_n  = cmd[`DDR_CSBIT];
828
        assign  o_ddr_ras_n = cmd[`DDR_RASBIT];
829
        assign  o_ddr_cas_n = cmd[`DDR_CASBIT];
830
        assign  o_ddr_we_n  = cmd[`DDR_WEBIT];
831 2 dgisselq
        assign  o_ddr_dqs   = drive_dqs;
832 3 dgisselq
        assign  o_ddr_addr  = cmd[(`DDR_ADDR_BITS-1):0];
833
        assign  o_ddr_ba    = cmd[(`DDR_BABITS+`DDR_ADDR_BITS-1):`DDR_ADDR_BITS];
834 7 dgisselq
        always @(posedge i_clk)
835
                o_ddr_data  <= bus_fifo_data[bus_fifo_tail];
836 3 dgisselq
        assign  w_precharge_all = (cmd[`DDR_CSBIT:`DDR_WEBIT]==`DDR_PRECHARGE)
837 2 dgisselq
                                &&(o_ddr_addr[10]); // 5 bits
838
 
839
        // Need to set o_wb_dqs high one clock prior to any read.
840
        // As per spec, ODT = 0 during reads
841 7 dgisselq
        assign  o_ddr_bus_oe = ~bus_read[`BUSNOW];
842 2 dgisselq
 
843 4 dgisselq
        // ODT must be in high impedence while reset_n=0, then it can be set
844
        // to low or high.
845
        assign  o_ddr_odt = o_ddr_bus_oe;
846 2 dgisselq
 
847 7 dgisselq
        always @(posedge i_clk)
848
                o_wb_ack <= pre_ack;
849
        always @(posedge i_clk)
850
                o_wb_data <= i_ddr_data;
851 4 dgisselq
 
852 2 dgisselq
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.