Subversion Repositories pentevo

Rev

Rev 896 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
668 lvd 1
// ZX-Evo Base Configuration (c) NedoPC 2008,2009,2010,2011,2012,2013,2014
4 lvd 2
//
3
// DRAM controller. performs accesses to DRAM.
668 lvd 4
 
5
/*
6
    This file is part of ZX-Evo Base Configuration firmware.
7
 
8
    ZX-Evo Base Configuration firmware is free software:
9
    you can redistribute it and/or modify it under the terms of
10
    the GNU General Public License as published by
11
    the Free Software Foundation, either version 3 of the License, or
12
    (at your option) any later version.
13
 
14
    ZX-Evo Base Configuration firmware is distributed in the hope that
15
    it will be useful, but WITHOUT ANY WARRANTY; without even
16
    the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17
    See the GNU General Public License for more details.
18
 
19
    You should have received a copy of the GNU General Public License
20
    along with ZX-Evo Base Configuration firmware.
21
    If not, see <http://www.gnu.org/licenses/>.
22
*/
23
 
24
 
4 lvd 25
//
668 lvd 26
//
4 lvd 27
// state:          | RD1   | RD2   | RD3   | RD4   | WR1   | WR2   | WR3   | WR4   | RFSH1 | RFSH2 | RFSH3 | RFSH4 |
28
// clk: ___/```\___/```\___/```\___/```\___/```\___/```\___/```\___/```\___/```\___/```\___/```\___/```\___/```\___/```\__
29
//                 |      READ CYCLE               |      WRITE CYCLE              |      REFRESH CYCLE            |
30
// ras: ```````````````````\_______________/```````````````\_______________/```````````````````````\_______________/
31
// cas: ```````````````````````````\_______________/```````````````\_______________/```````\_______________/````````
32
// ra:                 |  row  | column|               |  row  | column|
33
// rd:     XXXXXXXXXXXXXXXXXXXXXXXXX<read data read|  write data write data write  |
34
// rwe:   `````````````````````````````````````````\_______________________________/````````````````````````````````
35
// req:  __/```````\_______________________/```````\________________________________________________________________
36
// rnw:  XX/```````\XXXXXXXXXXXXXXXXXXXXXXX\_______/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
37
// cbeg: __________/```````\_______________________/```````\_______________________/```````\_______________________/
38
// rrdy: __________________________________/```````\________________________________________________________________
39
// addr: XX< addr  >XXXXXXXXXXXXXXXXXXXXXXX< addr  >XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
40
//wrdata:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX< write >XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
41
//rddata:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX< read  >XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
42
//
43
// comments:
44
// rucas_n, rlcas_n, rras0_n, rras1_n, rwe_n could be made 'fast output register'
45
// ra[] couldn't be such in acex1k, because output registers could be all driven only by
46
//  single clock polarity (and here they are driven by negative edge, while CAS/RAS by positive)
47
//
48
// rst_n is resynced before use and acts as req inhibit. so while in reset, dram regenerates and isn't corrupted
49
 
668 lvd 50
`include "../include/tune.v"
51
 
4 lvd 52
module dram(
53
 
54
        input clk,
55
        input rst_n, // shut down accesses, remain refresh
56
 
57
        output reg [9:0] ra, // to the DRAM pins
58
        inout     [15:0] rd, // .              .
59
                             // .              .
60
        output reg rwe_n,    // .              .
61
        output reg rucas_n,  // .              .
62
        output reg rlcas_n,  // .              .
63
        output reg rras0_n,  // .              .
64
        output reg rras1_n,  // to the DRAM pins
65
 
66
        input [20:0] addr, // access address of 16bit word: addr[0] selects between rras0_n and rras1_n,
67
                           // addr[10:1] goes to row address, addr[20:11] goes to column address
68
 
69
        input req,         // request for read/write cycle
70
        input rnw,         // READ/nWRITE (=1: read, =0: write)
71
 
72
        output reg cbeg,       // cycle begin (any including refresh), can be used for synchronizing
73
        output reg rrdy,       // Read data ReaDY
74
 
75
        output reg [15:0] rddata, // data just read
76
 
77
        input  [15:0] wrdata, // data to be written
78
        input   [1:0] bsel    // positive byte select for write: bsel[0] is for wrdata[7:0], bsel[1] is for wrdata[15:8]
79
 
80
 
81
);
82
 
83
        reg [1:0] rst_sync;
84
        wire reset;
85
        wire int_req;
86
 
87
        reg [20:0] int_addr;
88
        reg [15:0] int_wrdata;
89
        reg  [1:0] int_bsel;
90
 
91
 
92
        reg rfsh_alt; // we must alternate chips in refresh cycles to lower total heating
93
 
94
 
95
 
96
        reg [3:0] state;
97
        reg [3:0] next_state;
98
 
99
        localparam RD1   = 0;
100
        localparam RD2   = 1;
101
        localparam RD3   = 2;
102
        localparam RD4   = 3;
103
        localparam WR1   = 4;
104
        localparam WR2   = 5;
105
        localparam WR3   = 6;
106
        localparam WR4   = 7;
107
        localparam RFSH1 = 8;
108
        localparam RFSH2 = 9;
109
        localparam RFSH3 = 10;
110
        localparam RFSH4 = 11;
111
 
112
 
113
 
114
        initial
115
        begin
116
                state = RFSH1; // for simulation only!
117
                rfsh_alt = 1'b0;
118
        end
119
 
425 lvd 120
/*
200 lvd 121
`ifdef SIMULATE
4 lvd 122
        always @(posedge clk)
123
        begin
200 lvd 124
                if( req && !rnw && (state==RD4 || state==WR4 || state==RFSH4) )
125
                begin
126
                        $display("written word %x mask %x to address %x",wrdata&{ {8{bsel[1]}}, {8{bsel[0]}} },{ {8{bsel[1]}}, {8{bsel[0]}} },addr);
127
                end
128
        end
129
`endif
425 lvd 130
*/
200 lvd 131
 
132
        always @(posedge clk)
133
        begin
4 lvd 134
                state <= next_state;
135
        end
136
 
137
        always @*
138
                case( state )
139
 
140
                RD1:
141
                        next_state = RD2;
142
                RD2:
143
                        next_state = RD3;
144
                RD3:
145
                        next_state = RD4;
146
                RD4:
147
                        if( !int_req )
148
                                next_state = RFSH1;
149
                        else
150
                                next_state = rnw?RD1:WR1;
151
 
152
                WR1:
153
                        next_state = WR2;
154
                WR2:
155
                        next_state = WR3;
156
                WR3:
157
                        next_state = WR4;
158
                WR4:
159
                        if( !int_req )
160
                                next_state = RFSH1;
161
                        else
162
                                next_state = rnw?RD1:WR1;
163
 
164
 
165
                RFSH1:
166
                        next_state = RFSH2;
167
                RFSH2:
168
                        next_state = RFSH3;
169
                RFSH3:
170
                        next_state = RFSH4;
171
                RFSH4:
172
                        if( !int_req )
173
                                next_state = RFSH1;
174
                        else
175
                                next_state = rnw?RD1:WR1;
176
 
177
                endcase
178
 
179
 
180
        // incoming data latching
181
        always @(posedge clk)
182
        begin
183
                if( (state==RD4) || (state==WR4) || (state==RFSH4) )
184
                begin
185
                        int_addr   <= addr;
186
                        int_wrdata <= wrdata;
187
                        int_bsel   <= bsel;
188
                end
189
        end
190
 
191
        // WE control
192
        always @(posedge clk)
193
        begin
194
                if( (next_state==WR1) || (next_state==WR2) || (next_state==WR3) || (next_state==WR4) )
195
                        rwe_n <= 1'b0;
196
                else
197
                        rwe_n <= 1'b1;
198
        end
199
 
200
 
201
        // RAS/CAS sequencing
202
        always @(posedge clk)
203
        begin
204
                case( state )
205
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
206
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
207
                RD1:
208
                begin
209
                        rras0_n <= int_addr[0];
210
                        rras1_n <= ~int_addr[0];
211
                end
212
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
213
                RD2:
214
                begin
215
                        rucas_n <= 1'b0;
216
                        rlcas_n <= 1'b0;
217
                end
218
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
219
                RD3:
220
                begin
221
                        rras0_n <= 1'b1;
222
                        rras1_n <= 1'b1;
223
                end
224
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
225
                RD4:
226
                begin
227
                        rras0_n <= 1'b1;
228
                        rras1_n <= 1'b1;
229
                        rucas_n <= 1'b1;
230
                        rlcas_n <= 1'b1;
231
                end
232
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
233
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
234
                WR1:
235
                begin
236
                        rras0_n <= int_addr[0];
237
                        rras1_n <= ~int_addr[0];
238
                end
239
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
240
                WR2:
241
                begin
242
                        rucas_n <= ~int_bsel[1];
243
                        rlcas_n <= ~int_bsel[0];
244
                end
245
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
246
                WR3:
247
                begin
248
                        rras0_n <= 1'b1;
249
                        rras1_n <= 1'b1;
250
                end
251
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
252
                WR4:
253
                begin
254
                        rras0_n <= 1'b1;
255
                        rras1_n <= 1'b1;
256
                        rucas_n <= 1'b1;
257
                        rlcas_n <= 1'b1;
258
                end
259
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
260
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
261
                RFSH1:
262
                begin
263
                        rucas_n <= 1'b0;
264
                        rlcas_n <= 1'b0;
265
                end
266
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
267
                RFSH2:
268
                begin
269
                        rras0_n <=  rfsh_alt;
270
                        rras1_n <= ~rfsh_alt;
271
 
272
                        rfsh_alt <= ~rfsh_alt;
273
                end
274
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
275
                RFSH3:
276
                begin
277
                        rucas_n <= 1'b1;
278
                        rlcas_n <= 1'b1;
279
                end
280
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
281
                RFSH4:
282
                begin
283
                        rras0_n <= 1'b1;
284
                        rras1_n <= 1'b1;
285
                        rucas_n <= 1'b1;
286
                        rlcas_n <= 1'b1;
287
                end
288
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
289
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
290
                endcase
291
        end
292
 
293
 
294
        // row/column address multiplexing
295
        always @(negedge clk)
296
        begin
297
                if( (state==RD1) || (state==WR1) )
298
                        ra <= int_addr[10:1];
299
                else
300
                        ra <= int_addr[20:11];
301
        end
302
 
303
 
304
        // DRAM data bus control
305
        assign rd = rwe_n ? 16'hZZZZ : int_wrdata;
306
 
307
 
308
        // read data from DRAM
309
        always @(posedge clk)
310
        begin
311
                if( state==RD3 )
312
                        rddata <= rd;
313
        end
314
 
315
 
316
        // cbeg and rrdy control
317
        always @(posedge clk)
318
        begin
319
                if( (state==RD4) || (state==WR4) || (state==RFSH4) )
320
                        cbeg <= 1'b1;
321
                else
322
                        cbeg <= 1'b0;
323
 
324
 
325
            if( state==RD3 )
326
                rrdy <= 1'b1;
327
            else
328
                rrdy <= 1'b0;
329
        end
330
 
331
 
332
        // reset must be synchronous here in order to preserve
333
        // DRAM state while other modules reset, but we have only
334
        // asynchronous one globally. so we must re-synchronize it
335
        // and use it as 'DRAM operation enable'. when in reset,
336
        // controller ignores req signal and generates only refresh cycles
337
        always @(posedge clk)
338
                rst_sync[1:0] <= { rst_sync[0], ~rst_n };
339
 
340
        assign reset = rst_sync[1];
341
 
342
        assign int_req = req & (~reset);
343
 
344
endmodule