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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [orpsocv2/] [boards/] [xilinx/] [ml501/] [rtl/] [verilog/] [xilinx_ddr2/] [xilinx_ddr2_if.v] - Blame information for rev 439

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

Line No. Rev Author Line
1 412 julius
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  Xilinx DDR2 controller Wishbone Interface                   ////
4
////                                                              ////
5
////  Description                                                 ////
6
////  Simple interface to the Xilinx MIG generated DDR2 controller////
7
////                                                              ////
8
////  To Do:                                                      ////
9
////   Increase usage of cache BRAM to maximum (currently only    ////
10
////   256 bytes out of about 8192)                               ////
11
////   Make this a Wishbone B3 registered feedback burst friendly ////
12
////   server.                                                    ////
13
////                                                              ////
14
////  Author(s):                                                  ////
15
////      - Julius Baxter, julius.baxter@orsoc.se                 ////
16
////                                                              ////
17
////                                                              ////
18
//////////////////////////////////////////////////////////////////////
19
////                                                              ////
20
//// Copyright (C) 2010 Authors and OPENCORES.ORG                 ////
21
////                                                              ////
22
//// This source file may be used and distributed without         ////
23
//// restriction provided that this copyright statement is not    ////
24
//// removed from the file and that any derivative work contains  ////
25
//// the original copyright notice and the associated disclaimer. ////
26
////                                                              ////
27
//// This source file is free software; you can redistribute it   ////
28
//// and/or modify it under the terms of the GNU Lesser General   ////
29
//// Public License as published by the Free Software Foundation; ////
30
//// either version 2.1 of the License, or (at your option) any   ////
31
//// later version.                                               ////
32
////                                                              ////
33
//// This source is distributed in the hope that it will be       ////
34
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
35
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
36
//// PURPOSE.  See the GNU Lesser General Public License for more ////
37
//// details.                                                     ////
38
////                                                              ////
39
//// You should have received a copy of the GNU Lesser General    ////
40
//// Public License along with this source; if not, download it   ////
41
//// from http://www.opencores.org/lgpl.shtml                     ////
42
////                                                              ////
43
//////////////////////////////////////////////////////////////////////
44
/*
45
 * The controller is design to stream lots of data out at the DDR2 controller's
46
 * rate. All we implement here is enough to do the simplest accesses into a
47
 * small cache, which eases the domain crossing headaches.
48
 *
49
 * This was originally written to handle a DDR2 part which is doing burst length
50
 * of 4 as a minimum via a databus which is 64-bits wide.
51
 *
52
 * This means the smallest accesses is 4*64=256-bits or 32-bytes.
53
 *
54
 * We are bridging to a 32-bit wide system bus, so this means we must handle
55
 * accesses in 8-word lots.
56
 *
57
 * A simple cache mechanism has been implemented, meaning we check if the cached
58
 * data has been written to, and therefore needs writing back to the main memory
59
 * before any other access can occur.
60
 *
61
 * Cache memory:
62
 * The cache memory is a core-generated module, instantiating something out
63
 * of the XilinxCoreLib. The reason is because an arrangement or RAMB36s with
64
 * different sized A and B data in/out ports can't be instantiated directly
65
 * for some reason.
66
 * What we have is side A with 32-bits, and side B with 128-bits wide.
67
 *
68
 * TODO:
69
 * This only supports 8-words for now but can easily be expanded, although
70
 * multiple way/associativity caching will require some extra work to handle
71
 * multiple cached addresses.
72
 *
73
 * But it should be easy enough to make this thing cache as much as its RAMB
74
 * resources allow (4-RAMB16s becuase due to the 128-bit DDR2-side interface)
75
 * which is about 8Kbyte.
76
 *
77
 * Multi-cycle paths:
78
 * Write:
79
 * To indicate that a writeback is occuring, a system-bus domain (wishbone, in
80
 * this case) signal is set, and then sampled in the controller domain whenever
81
 * a system-bus domain clock edge is detected. This register is "do_writeback"
82
 * and then the controller domain register "ddr2_write_done" is asserted when
83
 * the data has been written out of the RAMs and into the controller's fifos.
84
 * "ddr2_write_done" is then sampled by the system-bus domain and "do_writeback"
85
 * So there are paths between:
86
 * ( register -> (sampled by) -> register )
87
 * wb_clk:do_writeback -> ddr2_clk:do_writeback_ddr2_shifter
88
 * wb_clk:do_writeback -> ddr2_clk:ddr2_write_done
89
 * ddr2_clk:ddr2_write_done -> wb_clk:do_writeback
90
 *
91
 * Read:
92
 * The only signal crossing we have here is the one indicating the read data
93
 * has arrived into the cache RAM from the controller. The controller domain
94
 * register "ddr2_read_done" is set, and sampled in the system-bus domain by the
95
 * logic controlling the "do_readfrom" register. "ddr2_read_done" is cleared
96
 * when the controller domain sees that "do_readfrom" has been de-asserted.
97
 * So there are paths between:
98
 * ( register -> (sampled by) -> register )
99
 * ddr2_clk:ddr2_read_done -> wb_clk:do_readfrom
100
 * wb_clk:do_readfrom -> ddr2_clk:ddr2_read_done
101
 *
102
 */
103
module xilinx_ddr2_if (
104
    input [31:0]       wb_adr_i,
105
    input              wb_stb_i,
106
    input              wb_cyc_i,
107 439 julius
    input [2:0]        wb_cti_i,
108
    input [1:0]        wb_bte_i,
109 412 julius
    input              wb_we_i,
110
    input [3:0]        wb_sel_i,
111
    input [31:0]       wb_dat_i,
112
    output [31:0]      wb_dat_o,
113
    output reg         wb_ack_o,
114
 
115
    output [12:0]      ddr2_a,
116
    output [1:0]       ddr2_ba,
117
    output             ddr2_ras_n,
118
    output             ddr2_cas_n,
119
    output             ddr2_we_n,
120
    output [1:0]       ddr2_cs_n,
121
    output [1:0]       ddr2_odt,
122
    output [1:0]       ddr2_cke,
123
    output [7:0]       ddr2_dm,
124
 
125
    inout [63:0]       ddr2_dq,
126
    inout [7:0]        ddr2_dqs,
127
    inout [7:0]        ddr2_dqs_n,
128
    output [1:0]       ddr2_ck,
129
    output [1:0]       ddr2_ck_n,
130
 
131
    input              ddr2_if_clk,
132
    input              ddr2_if_rst,
133
    input              idly_clk_200,
134
    input              wb_clk,
135
    input              wb_rst);
136
 
137
`include "xilinx_ddr2_params.v"
138
 
139
   wire                ddr2_clk; // DDR2 iface domain clock.
140
   wire                ddr2_rst; // reset from the ddr2 module
141
 
142
   wire                wb_req;
143
   reg                 wb_req_r;
144
   reg                 wb_ack_o_r;
145
 
146
   wire                wb_req_new;
147
   reg                 wb_req_new_r;
148
 
149
   reg                 wb_req_addr_hit;
150
 
151
   reg                 cached_addr_valid;
152
 
153
   reg [31:6]          cached_addr;
154
 
155
   wire                cache_hit;
156
 
157
   reg                 cache_dirty;
158
 
159
   reg [2:0]            wb_req_cache_word_addr;
160
 
161
   wire                wb_cache_en;
162
 
163
   reg                 do_writeback, do_writeback_r;
164
   wire                do_writeback_start, do_writeback_finished;
165
   wire                doing_writeback;
166
 
167
   reg                 do_readfrom, do_readfrom_r;
168
   wire                do_readfrom_start, do_readfrom_finished;
169
   wire                doing_readfrom;
170
 
171
 
172
   // Domain crossing logic
173
   reg                 wb_clk_r;
174
   reg                 wb_clk_in_ddr2_clk;
175
 
176
   reg                 wb_clk_in_ddr2_clk_r;
177
   wire                wb_clk_edge;
178
   reg [2:0]            ddr2_clk_phase;
179
   // Sample when clk phase is 0
180
   reg [7:0]            do_writeback_ddr2_shifter;
181
   reg [7:0]            do_writeback_ddr2_shifter_r;
182
   reg                 do_writeback_ddr2_fifo_we;
183
   reg                 ddr2_write_done;
184
 
185
   // Currently, ddr2-side of cache is address is a single bit
186
   reg [1:0]            ddr2_cache_addr;
187
   wire [127:0]        ddr2_cache_data_o;
188
   reg                 rd_data_valid_r;
189
   reg                 ddr2_read_done;
190
 
191
   // DDR2 MIG interface wires
192
   wire                app_af_afull;
193
   wire                app_wdf_afull;
194
   wire                app_wdf_wren;
195
   wire                app_af_wren;
196
   wire [30:0]          app_af_addr;
197
   wire [2:0]           app_af_cmd;
198
   wire [(APPDATA_WIDTH)-1:0] app_wdf_data;
199
   wire [(APPDATA_WIDTH/8)-1:0] app_wdf_mask_data;
200
   wire                         rd_data_valid;
201
   wire [(APPDATA_WIDTH)-1:0]    rd_data_fifo_out;
202
   wire                         phy_init_done;
203
 
204
   assign cache_hit = (cached_addr ==  wb_adr_i[31:6]) & cached_addr_valid;
205
 
206
   // Wishbone request detection
207
   assign wb_req = wb_stb_i & wb_cyc_i & phy_init_done;
208
 
209
   always @(posedge wb_clk)
210
     wb_req_r <= wb_req;
211
 
212
   assign wb_req_new = wb_req & !wb_req_r;
213
 
214
   always @(posedge wb_clk)
215
     wb_req_new_r <= wb_req_new;
216
 
217
   // Register whether it's a hit or not
218
   // As more lines are added, add them to this check.
219
   always @(posedge wb_clk)
220
     if (wb_rst)
221
       wb_req_addr_hit <= 0;
222
     else
223
       wb_req_addr_hit <= wb_req & cache_hit & cached_addr_valid;
224
 
225
   always @(posedge wb_clk)
226
     if (wb_rst)
227
       wb_ack_o <= 0;
228
     else
229
       wb_ack_o <= wb_req_addr_hit & !wb_ack_o & !wb_ack_o_r;
230
 
231
   always @(posedge wb_clk)
232
     wb_ack_o_r <= wb_ack_o;
233
 
234
   // Address valid logic
235
   always @(posedge wb_clk)
236
     if (wb_rst)
237
       cached_addr_valid <= 0;
238
     else if (do_readfrom_finished)
239
       cached_addr_valid <= 1;
240
     else if ( do_writeback_finished ) // Data written back, cache not valid
241
       cached_addr_valid <= 0;
242
     else if (wb_req & !cache_hit & cached_addr_valid & !cache_dirty)
243
       // Invalidate cache so a readfrom begins
244
       cached_addr_valid <= 0;
245
 
246
   // Address cacheing
247
   always @(posedge wb_clk)
248
     if (wb_rst)
249
       cached_addr <= 0;
250
     else if (do_readfrom_start)
251
       cached_addr <= wb_adr_i[31:6];
252
 
253
   // Cache dirty signal
254
   always @(posedge wb_clk)
255
     if (wb_rst)
256
       cache_dirty <= 0;
257
     else if (wb_req & wb_we_i & wb_req_addr_hit & wb_ack_o)
258
       cache_dirty <= 1;
259
     else if (!cached_addr_valid & cache_dirty)
260
       cache_dirty <= 0;
261
 
262
   // Wishbone side of cache enable. Important!
263
   // 1. Enable on first access, if it's not a write
264
   // 2. Enable if we've just refreshed the cache
265
   // 3. Enable on ACK'ing for a write
266
   assign wb_cache_en = (wb_req_new & !wb_we_i) | do_readfrom_finished |
267
                        (wb_req_addr_hit & wb_stb_i & !wb_we_i & !wb_ack_o) |
268
                        (wb_ack_o & wb_we_i);
269
 
270
   // Writeback detect logic
271
   always @(posedge wb_clk)
272
     if (wb_rst)
273
       do_writeback <= 0;
274
     else if (ddr2_write_done) // DDR2 domain signal
275
       do_writeback <= 0;
276
     else if (wb_req & !cache_hit & cached_addr_valid & !doing_writeback & cache_dirty)
277
       do_writeback <= 1;
278
 
279
 
280
   always @(posedge wb_clk)
281
     do_writeback_r <= do_writeback;
282
 
283
   assign do_writeback_start = do_writeback & !do_writeback_r;
284
   assign do_writeback_finished = !do_writeback & do_writeback_r;
285
   assign doing_writeback = do_writeback | do_writeback_r;
286
 
287
   // DDR2 Read detect logic
288
   always @(posedge wb_clk)
289
     if (wb_rst)
290
       do_readfrom <= 0;
291
     else if (ddr2_read_done) // DDR2 domain signal
292
       do_readfrom <= 0;
293
     else if (wb_req & !cache_hit & !cached_addr_valid & !doing_readfrom & !cache_dirty)
294
       do_readfrom <= 1;
295
 
296
   always @(posedge wb_clk)
297
     do_readfrom_r <= do_readfrom;
298
 
299
   assign do_readfrom_start = do_readfrom & !do_readfrom_r;
300
   assign do_readfrom_finished = !do_readfrom & do_readfrom_r;
301
   assign doing_readfrom = do_readfrom | do_readfrom_r;
302
 
303
   // Address fifo signals
304
   assign app_af_wren = (do_writeback_finished | do_readfrom_start);
305
   assign app_af_cmd[0] = do_readfrom_start; // 1 - read, 0 - write
306
   assign app_af_cmd[2:1] = 0;
307
   assign app_af_addr = do_readfrom_start ?  {2'd0, wb_adr_i[31:6],3'd0} :
308
                        {2'd0,cached_addr,3'd0};
309
 
310
   assign app_wdf_wren = do_writeback_ddr2_fifo_we;
311
   assign app_wdf_data = ddr2_cache_data_o;
312
   assign app_wdf_mask_data = 0;
313
 
314
   always @(posedge wb_clk) if (wb_rst) wb_clk_r <= 0; else wb_clk_r <= ~wb_clk_r;
315
   always @(posedge ddr2_clk) wb_clk_in_ddr2_clk <= wb_clk_r;
316
   always @(posedge ddr2_clk) wb_clk_in_ddr2_clk_r <= wb_clk_in_ddr2_clk;
317
 
318
   assign wb_clk_edge = wb_clk_in_ddr2_clk & !wb_clk_in_ddr2_clk_r;
319
 
320
   always @(posedge ddr2_clk)
321
     if (ddr2_rst)
322
       ddr2_clk_phase <= 0;
323
     else if (wb_clk_edge)
324
       ddr2_clk_phase <= 0;
325
     else
326
       ddr2_clk_phase <= ddr2_clk_phase + 1;
327
 
328
   always @(posedge ddr2_clk)
329
     do_writeback_ddr2_fifo_we <= (do_writeback_ddr2_shifter_r[0]) |
330
                                  (do_writeback_ddr2_shifter_r[2]) |
331
                                  (do_writeback_ddr2_shifter_r[4]) |
332
                                  (do_writeback_ddr2_shifter_r[6]);
333
 
334
   // Kick off counting when we see that the wb_clk domain is
335
   // doing a writeback.
336
   always @(posedge ddr2_clk)
337
     if (ddr2_rst)
338
       do_writeback_ddr2_shifter <= 4'h0;
339
     else if  (|do_writeback_ddr2_shifter)
340
       do_writeback_ddr2_shifter <= {do_writeback_ddr2_shifter[6:0], 1'b0};
341
     else if (!(|ddr2_clk_phase) & do_writeback & !ddr2_write_done) // sample WB domain
342
       do_writeback_ddr2_shifter <= 1;
343
 
344
 
345
 
346
   always @(posedge ddr2_clk)
347
     do_writeback_ddr2_shifter_r <= do_writeback_ddr2_shifter;
348
 
349
   always @(posedge ddr2_clk)
350
     if (ddr2_rst)
351
       ddr2_write_done <= 0;
352
     else if (do_writeback_ddr2_shifter[7])
353
       ddr2_write_done <= 1;
354
     else if ((!(|ddr2_clk_phase)) & !do_writeback) // sample WB domain
355
       ddr2_write_done <= 0;
356
 
357
   always @(posedge ddr2_clk)
358
     if (ddr2_rst)
359
       ddr2_cache_addr <= 0;
360
     else if (rd_data_valid | do_writeback_ddr2_fifo_we)
361
       ddr2_cache_addr <= ddr2_cache_addr + 1;
362
 
363
   always @(posedge ddr2_clk)
364
     rd_data_valid_r <= rd_data_valid;
365
 
366
   // Read done signaling to WB domain
367
   always @(posedge ddr2_clk)
368
     if (ddr2_rst)
369
       ddr2_read_done <= 0;
370 439 julius
   // Detect read data valid falling edge
371
     else if (!rd_data_valid & rd_data_valid_r)
372 412 julius
       ddr2_read_done <= 1;
373
     else if (!(|ddr2_clk_phase) & !do_readfrom) // Read WB domain
374
       ddr2_read_done <= 0;
375
 
376
   wire [3:0]                    wb_cache_adr;
377
   assign wb_cache_adr = wb_adr_i[5:2];
378
   wire [3:0]                    wb_cache_sel_we;
379
   assign wb_cache_sel_we = {4{wb_we_i}} & wb_sel_i;
380
   wire                         ddr2_cache_en;
381
   wire [15:0]                   ddr2_cache_we;
382
   assign ddr2_cache_en = rd_data_valid | (|do_writeback_ddr2_shifter);
383
   assign ddr2_cache_we = {16{rd_data_valid}};
384
 
385
 
386
   // Xilinx Coregen true dual-port RAMB array.
387
   // Wishbone side : 32-bit
388
   // DDR2 side : 128-bit
389
   xilinx_ddr2_if_cache cache_mem0
390
     (
391
      // Wishbone side
392
      .clka(wb_clk),
393
      .ena(wb_cache_en),
394
      .wea(wb_cache_sel_we),
395
      .addra({8'd0,wb_cache_adr}),
396
      .dina(wb_dat_i),
397
      .douta(wb_dat_o),
398
 
399
      // DDR2 controller side
400
      .clkb(ddr2_clk),
401
      .enb(ddr2_cache_en),
402
      .web(ddr2_cache_we),
403
      .addrb({8'd0,ddr2_cache_addr}),
404
      .dinb(rd_data_fifo_out),
405
      .doutb(ddr2_cache_data_o));
406
 
407
   ddr2_mig #
408
     (
409
      .BANK_WIDTH            (BANK_WIDTH),
410
      .CKE_WIDTH             (CKE_WIDTH),
411
      .CLK_WIDTH             (CLK_WIDTH),
412
      .COL_WIDTH             (COL_WIDTH),
413
      .CS_NUM                (CS_NUM),
414
      .CS_WIDTH              (CS_WIDTH),
415
      .CS_BITS               (CS_BITS),
416
      .DM_WIDTH              (DM_WIDTH),
417
      .DQ_WIDTH              (DQ_WIDTH),
418
      .DQ_PER_DQS            (DQ_PER_DQS),
419
      .DQ_BITS               (DQ_BITS),
420
      .DQS_WIDTH             (DQS_WIDTH),
421
      .DQS_BITS              (DQS_BITS),
422
      .HIGH_PERFORMANCE_MODE (HIGH_PERFORMANCE_MODE),
423
      .ODT_WIDTH             (ODT_WIDTH),
424
      .ROW_WIDTH             (ROW_WIDTH),
425
      .APPDATA_WIDTH         (APPDATA_WIDTH),
426
      .ADDITIVE_LAT          (ADDITIVE_LAT),
427
      .BURST_LEN             (BURST_LEN),
428
      .BURST_TYPE            (BURST_TYPE),
429
      .CAS_LAT               (CAS_LAT),
430
      .ECC_ENABLE            (ECC_ENABLE),
431
      .MULTI_BANK_EN         (MULTI_BANK_EN),
432
      .ODT_TYPE              (ODT_TYPE),
433
      .REDUCE_DRV            (REDUCE_DRV),
434
      .REG_ENABLE            (REG_ENABLE),
435
      .TREFI_NS              (TREFI_NS),
436
      .TRAS                  (TRAS),
437
      .TRCD                  (TRCD),
438
      .TRFC                  (TRFC),
439
      .TRP                   (TRP),
440
      .TRTP                  (TRTP),
441
      .TWR                   (TWR),
442
      .TWTR                  (TWTR),
443
      .SIM_ONLY              (SIM_ONLY),
444
      .RST_ACT_LOW           (RST_ACT_LOW),
445
      .CLK_TYPE              (CLK_TYPE),
446
      .DLL_FREQ_MODE         (DLL_FREQ_MODE),
447
      .CLK_PERIOD            (CLK_PERIOD)
448
      )
449
   ddr2_mig0
450
     (
451
      .sys_clk           (ddr2_if_clk),
452
      .idly_clk_200      (idly_clk_200),
453
      .sys_rst_n         (ddr2_if_rst), // Act. high, sync. to ddr2_if_clk
454
      .ddr2_ras_n        (ddr2_ras_n),
455
      .ddr2_cas_n        (ddr2_cas_n),
456
      .ddr2_we_n         (ddr2_we_n),
457
      .ddr2_cs_n         (ddr2_cs_n),
458
      .ddr2_cke          (ddr2_cke),
459
      .ddr2_odt          (ddr2_odt),
460
      .ddr2_dm           (ddr2_dm),
461
      .ddr2_dq           (ddr2_dq),
462
      .ddr2_dqs          (ddr2_dqs),
463
      .ddr2_dqs_n        (ddr2_dqs_n),
464
      .ddr2_ck           (ddr2_ck),
465
      .ddr2_ck_n         (ddr2_ck_n),
466
      .ddr2_ba           (ddr2_ba),
467
      .ddr2_a            (ddr2_a),
468
 
469
      .clk0_tb           (ddr2_clk),
470
      .rst0_tb           (ddr2_rst),
471
      .usr_clk           (wb_clk),
472
      .app_af_afull      (app_af_afull),
473
      .app_wdf_afull     (app_wdf_afull),
474
      .rd_data_valid     (rd_data_valid),
475
      .rd_data_fifo_out  (rd_data_fifo_out),
476
      .app_af_wren       (app_af_wren),
477
      .app_af_cmd        (app_af_cmd),
478
      .app_af_addr       (app_af_addr),
479
      .app_wdf_wren      (app_wdf_wren),
480
      .app_wdf_data      (app_wdf_data),
481
      .app_wdf_mask_data (app_wdf_mask_data),
482
      .phy_init_done     (phy_init_done)
483
      );
484
 
485
 
486
endmodule // ml501_ddr2_if
487
// Local Variables:
488
// verilog-library-directories:("." "ddr2_mig")
489
// verilog-library-extensions:(".v" ".h")
490
// End:

powered by: WebSVN 2.1.0

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