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

Subversion Repositories m1_core

[/] [m1_core/] [trunk/] [hdl/] [rtl/] [wb_ddr_ctrl/] [ddr_ctrl.v] - Blame information for rev 54

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 34 fafa1971
//----------------------------------------------------------------------------
2
// Pipelined, asyncronous DDR Controller
3
//
4
// (c) Joerg Bornschein (<jb@capsec.org>)
5
//----------------------------------------------------------------------------
6
`include "ddr_include.v"
7
 
8
module ddr_ctrl
9
#(
10
        parameter phase_shift  = 0,
11
        parameter clk_multiply = 12,
12
        parameter clk_divide   = 5,
13
        parameter wait200_init = 26
14
) (
15
        input                   clk,
16
        input                   reset,
17
        // Temporary DCM control input
18
        input  [2:0]            rot,     // XXX
19
        //  DDR ports
20
        output                  ddr_clk,
21
        output                  ddr_clk_n,
22
        input                   ddr_clk_fb,
23
        output                  ddr_ras_n,
24
        output                  ddr_cas_n,
25
        output                  ddr_we_n,
26
        output                  ddr_cke,
27
        output                  ddr_cs_n,
28
        output [  `A_RNG]       ddr_a,
29
        output [ `BA_RNG]       ddr_ba,
30
        inout  [ `DQ_RNG]       ddr_dq,
31
        inout  [`DQS_RNG]       ddr_dqs,
32
        output [ `DM_RNG]       ddr_dm,
33
        // FML (FastMemoryLink)
34
        output reg              fml_done,
35
        input  [`FML_ADR_RNG]   fml_adr,
36
        input                   fml_rd,
37
        input                   fml_wr,
38
        input  [`FML_DAT_RNG]   fml_wdat,
39
        input  [`FML_BE_RNG]    fml_wbe,
40
        input                   fml_wnext,
41
        output                  fml_rempty,
42
        input                   fml_rnext,
43
        output [`FML_DAT_RNG]   fml_rdat
44
);
45
 
46
wire [ `DQ_RNG]       ddr_dq_i,  ddr_dq_o;
47
wire [`DQS_RNG]       ddr_dqs_i, ddr_dqs_o;
48
wire                  ddr_dqs_oe;
49
 
50
//----------------------------------------------------------------------------
51
// clock generator
52
//----------------------------------------------------------------------------
53
wire clk_locked;
54
wire write_clk, write_clk90;
55
wire read_clk;
56
 
57
wire reset_int = reset | ~clk_locked;
58
 
59
ddr_clkgen #(
60
        .phase_shift(  phase_shift  ),
61
        .clk_multiply( clk_multiply ),
62
        .clk_divide(   clk_divide   )
63
) clkgen (
64
        .clk(             clk            ),
65
        .reset(           reset          ),
66
        .locked(          clk_locked     ),
67
        // ddr-clk 
68
        .write_clk(       write_clk      ),
69
        .write_clk90(     write_clk90    ),
70
        // ddr-read-clk
71
        .ddr_clk_fb(      ddr_clk_fb     ),
72
        .read_clk(        read_clk       ),
73
        // phase shift control
74
        .rot(             rot            )      // XXX
75
);
76
 
77
//----------------------------------------------------------------------------
78
// async_fifos (cmd, wdata, rdata)
79
//----------------------------------------------------------------------------
80
wire                  cba_fifo_full;
81
reg  [`CBA_RNG]       cba_fifo_din;
82
reg                   cba_fifo_we;
83
 
84
wire                  wfifo_full;
85
wire  [`WFIFO_RNG]    wfifo_din;
86
wire                  wfifo_we;
87
 
88
wire [`RFIFO_RNG]     rfifo_dout;
89
wire                  rfifo_empty;
90
wire                  rfifo_next;
91
 
92
assign wfifo_din  = { ~fml_wbe, fml_wdat };
93
assign wfifo_we   = fml_wnext;
94
 
95
assign fml_rdat   = rfifo_dout;
96
assign fml_rempty = rfifo_empty;
97
assign rfifo_next = fml_rnext;
98
 
99
//----------------------------------------------------------------------------
100
// High-speed cmd, write and read datapath
101
//----------------------------------------------------------------------------
102
ddr_wpath wpath0 (
103
        .clk(         write_clk    ),
104
        .clk90(       write_clk90  ),
105
        .reset(       reset_int    ),
106
        // CBA async fifo
107
        .cba_clk(     clk           ),
108
        .cba_din(     cba_fifo_din  ),
109
        .cba_wr(      cba_fifo_we   ),
110
        .cba_full(    cba_fifo_full ),
111
        // WDATA async fifo
112
        .wdata_clk(   clk           ),
113
        .wdata_din(   wfifo_din     ),
114
        .wdata_wr(    wfifo_we      ),
115
        .wdata_full(  wfifo_full    ),
116
        //
117
        .sample(     sample      ),
118
        // DDR
119
        .ddr_clk(     ddr_clk    ),
120
        .ddr_clk_n(   ddr_clk_n  ),
121
        .ddr_ras_n(   ddr_ras_n  ),
122
        .ddr_cas_n(   ddr_cas_n  ),
123
        .ddr_we_n(    ddr_we_n   ),
124
        .ddr_a(       ddr_a      ),
125
        .ddr_ba(      ddr_ba     ),
126
        .ddr_dm(      ddr_dm     ),
127
        .ddr_dq(      ddr_dq_o   ),
128
        .ddr_dqs(     ddr_dqs_o  ),
129
        .ddr_dqs_oe(  ddr_dqs_oe )
130
);
131
 
132
ddr_rpath rpath0 (
133
        .clk(         read_clk   ),
134
        .reset(       reset_int  ),
135
        // 
136
        .sample(      sample     ),
137
        //
138
        .rfifo_clk(   clk        ),
139
        .rfifo_empty( rfifo_empty),
140
        .rfifo_dout(  rfifo_dout ),
141
        .rfifo_next(  rfifo_next ),
142
        // DDR
143
        .ddr_dq(      ddr_dq_i   ),
144
        .ddr_dqs(     ddr_dqs_i  )
145
);
146
 
147
//----------------------------------------------------------------------------
148
// 7.8 us pulse generator
149
//----------------------------------------------------------------------------
150
wire pulse78;
151
reg  ar_req;
152
reg  ar_done;
153
 
154
ddr_pulse78 pulse79_gen (
155
        .clk(     clk        ),
156
        .reset(   reset_int  ),
157
        .pulse78( pulse78    )
158
);
159
 
160
//----------------------------------------------------------------------------
161
// Auto Refresh request generator
162
//----------------------------------------------------------------------------
163
always @(posedge clk)
164
        if (reset_int)
165
                ar_req <= 0;
166
        else
167
                ar_req <= pulse78 | (ar_req & ~ar_done);
168
 
169
// operations we might want to submit
170
wire [`CBA_RNG] ar_pre_cba;
171
wire [`CBA_RNG] ar_ar_cba;
172
 
173
assign ar_pre_cba   = { `DDR_CMD_PRE, 2'b00, 13'b1111111111111 };
174
assign ar_ar_cba    = { `DDR_CMD_AR,  2'b00, 13'b0000000000000 };
175
 
176
//----------------------------------------------------------------------------
177
// Init & management
178
//----------------------------------------------------------------------------
179
wire                 init_req;
180
reg                  init_ack;
181
wire [`CBA_RNG]      init_cba;
182
wire                 init_done;
183
wire                 wait200;
184
 
185
ddr_init #(
186
        .wait200_init( wait200_init )
187
) init (
188
        .clk(         clk         ),
189
        .reset(       reset_int   ),
190
        .pulse78(     pulse78     ),
191
        .wait200(     wait200     ),
192
        .init_done(   init_done   ),
193
        //
194
        .mngt_req(    init_req    ),
195
        .mngt_ack(    init_ack    ),
196
        .mngt_cba(    init_cba    )
197
);
198
 
199
//----------------------------------------------------------------------------
200
// Active Bank Information 
201
//----------------------------------------------------------------------------
202
reg [`ROW_RNG] ba_row [3:0];
203
reg [3:0]      ba_active;
204
 
205
//----------------------------------------------------------------------------
206
// FML decoding
207
//----------------------------------------------------------------------------
208
wire [`FML_ADR_BA_RNG]    fml_ba  = fml_adr[`FML_ADR_BA_RNG];
209
wire [`FML_ADR_ROW_RNG]   fml_row = fml_adr[`FML_ADR_ROW_RNG];
210
wire [`FML_ADR_COL_RNG]   fml_col = fml_adr[`FML_ADR_COL_RNG];
211
 
212
wire [`FML_ADR_ROW_RNG]   fml_cur_row;   // current active row in sel. bank
213
assign fml_cur_row    = ba_row[fml_ba];
214
 
215
wire   fml_row_active;  // is row in selected ba really active?
216
assign fml_row_active = ba_active[fml_ba];
217
 
218
 
219
/*
220
wire   fml_row_active = (fml_ba == 0) ? ba0_active :     // is row in selected
221
                        (fml_ba == 1) ? ba1_active :     // bank really active?
222
                        (fml_ba == 2) ? ba2_active :
223
                                        ba3_active ;
224
*/
225
 
226
// request operation iff correct bank is active
227
wire fml_req       = fml_rd | fml_wr;
228
wire fml_row_match = (fml_row == fml_cur_row) & fml_row_active;
229
wire fml_pre_req   = fml_req & ~fml_row_match & fml_row_active;
230
wire fml_act_req   = fml_req & ~fml_row_active;
231
wire fml_read_req  = fml_rd  &  fml_row_match & ~fml_done;
232
wire fml_write_req = fml_wr  &  fml_row_match & ~fml_done;
233
 
234
// actual operations we might want to submit
235
wire [`CBA_RNG] fml_pre_cba;
236
wire [`CBA_RNG] fml_act_cba;
237
wire [`CBA_RNG] fml_read_cba;
238
wire [`CBA_RNG] fml_write_cba;
239
 
240
assign fml_pre_cba   = { `DDR_CMD_PRE,   fml_ba, 13'b0  };
241
assign fml_act_cba   = { `DDR_CMD_ACT,   fml_ba, fml_row };
242
assign fml_read_cba  = { `DDR_CMD_READ,  fml_ba, {3'b000}, fml_col, {3'b000} };
243
assign fml_write_cba = { `DDR_CMD_WRITE, fml_ba, {3'b000}, fml_col, {3'b000} };
244
 
245
//----------------------------------------------------------------------------
246
// Schedule and issue commands
247
//----------------------------------------------------------------------------
248
 
249
parameter s_init      = 0;
250
parameter s_idle      = 1;
251
parameter s_ar        = 2;
252
parameter s_reading   = 3;
253
 
254
reg [1:0] state;
255
 
256
always @(posedge clk)
257
begin
258
        if (reset_int) begin
259
                state        <= s_init;
260
                ba_active    <= 0;
261
                ba_row[0]    <= 0;
262
                ba_row[1]    <= 0;
263
                ba_row[2]    <= 0;
264
                ba_row[3]    <= 0;
265
 
266
                fml_done     <= 0;
267
                init_ack     <= 0;
268
                cba_fifo_we  <= 0;
269
                ar_done      <= 0;
270
        end else begin
271
                fml_done     <= 0;
272
                init_ack     <= 0;
273
                cba_fifo_we  <= 0;
274
                ar_done      <= 0;
275
 
276
                case (state)
277
                        s_init: begin
278
                                if (init_done)
279
                                        state <= s_idle;
280
 
281
                                if (init_req & ~cba_fifo_full) begin
282
                                        cba_fifo_we       <= 1;
283
                                        cba_fifo_din      <= init_cba;
284
                                        init_ack          <= 1;
285
                                end
286
                        end
287
                        s_idle: begin
288
                                if (fml_read_req & ~cba_fifo_full) begin
289
                                        cba_fifo_we       <= 1;
290
                                        cba_fifo_din      <= fml_read_cba;
291
                                        fml_done          <= 1;
292
                                end else if (fml_write_req & ~cba_fifo_full) begin
293
                                        cba_fifo_we       <= 1;
294
                                        cba_fifo_din      <= fml_write_cba;
295
                                        fml_done          <= 1;
296
                                end else if (ar_req & ~cba_fifo_full) begin
297
                                        cba_fifo_we       <= 1;
298
                                        cba_fifo_din      <= ar_pre_cba;
299
                                        ar_done           <= 1;
300
                                        ba_active         <= 'b0;
301
                                        state             <= s_ar;
302
                                end else if (fml_pre_req & ~cba_fifo_full) begin
303
                                        cba_fifo_we       <= 1;
304
                                        cba_fifo_din      <= fml_pre_cba;
305
                                        ba_active[fml_ba] <= 0;
306
                                end else if (fml_act_req & ~cba_fifo_full) begin
307
                                        cba_fifo_we       <= 1;
308
                                        cba_fifo_din      <= fml_act_cba;
309
                                        ba_active[fml_ba] <= 1;
310
                                        ba_row[fml_ba]    <= fml_row;
311
                                end
312
                        end
313
                        s_ar: begin
314
                                if (~cba_fifo_full) begin
315
                                        cba_fifo_we       <= 1;
316
                                        cba_fifo_din      <= ar_ar_cba;
317
                                        state             <= s_idle;
318
                                end
319
                        end
320
                endcase
321
        end
322
end
323
 
324
//----------------------------------------------------------------------------
325
// Demux dqs and dq
326
//----------------------------------------------------------------------------
327
assign ddr_cke   = ~wait200;     // bring up CKE as soon 200us wait is finished
328
 
329
assign ddr_dqs = ddr_dqs_oe!=1'b0 ? ddr_dqs_o : 'bz;
330
assign ddr_dq  = ddr_dqs_oe!=1'b0 ? ddr_dq_o  : 'bz;
331
 
332
assign ddr_dqs_i = ddr_dqs;
333
assign ddr_dq_i  = ddr_dq;
334
 
335
assign ddr_cs_n = 0;
336
 
337
endmodule
338
 
339
// vim: set ts=4

powered by: WebSVN 2.1.0

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