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

Subversion Repositories vg_z80_sbc

[/] [vg_z80_sbc/] [trunk/] [rtl/] [ddr_ctrl.v] - Blame information for rev 35

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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