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 503

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

Line No. Rev Author Line
1 412 julius
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3 479 julius
////  Xilinx ML501 DDR2 controller Wishbone Interface             ////
4 412 julius
////                                                              ////
5
////  Description                                                 ////
6
////  Simple interface to the Xilinx MIG generated DDR2 controller////
7
////                                                              ////
8
////  To Do:                                                      ////
9 479 julius
////   Use full capacity of BRAM                                  ////
10
////   Employ LRU replacement scheme                              ////
11
////   Remove hard-coding of things relating to number of lines   ////
12 412 julius
////                                                              ////
13
////  Author(s):                                                  ////
14
////      - Julius Baxter, julius.baxter@orsoc.se                 ////
15
////                                                              ////
16
////                                                              ////
17
//////////////////////////////////////////////////////////////////////
18
////                                                              ////
19
//// Copyright (C) 2010 Authors and OPENCORES.ORG                 ////
20
////                                                              ////
21
//// This source file may be used and distributed without         ////
22
//// restriction provided that this copyright statement is not    ////
23
//// removed from the file and that any derivative work contains  ////
24
//// the original copyright notice and the associated disclaimer. ////
25
////                                                              ////
26
//// This source file is free software; you can redistribute it   ////
27
//// and/or modify it under the terms of the GNU Lesser General   ////
28
//// Public License as published by the Free Software Foundation; ////
29
//// either version 2.1 of the License, or (at your option) any   ////
30
//// later version.                                               ////
31
////                                                              ////
32
//// This source is distributed in the hope that it will be       ////
33
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
34
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
35
//// PURPOSE.  See the GNU Lesser General Public License for more ////
36
//// details.                                                     ////
37
////                                                              ////
38
//// You should have received a copy of the GNU Lesser General    ////
39
//// Public License along with this source; if not, download it   ////
40
//// from http://www.opencores.org/lgpl.shtml                     ////
41
////                                                              ////
42
//////////////////////////////////////////////////////////////////////
43
/*
44 479 julius
 * This is an interface to the Xilinx MIG-sourced DDR2 controller.
45 412 julius
 *
46 479 julius
 * The controller's interface is via FIFO buffers - one for address and control
47
 * the other is for data. The data FIFO interface is 128-bits wide.
48 412 julius
 *
49 479 julius
 * This module has a cache with different aspects on each port. As we're to
50
 * ultimately interface to a 32-bit wide Wishbone bus, one side is 32-bits
51
 * and the other is 128-bits wide to accommodate the DDR2 controller's data
52
 * path.
53 412 julius
 *
54 479 julius
 * At present, the cache controller doesn't employ associativity, so any
55
 * line can be used for any location. A round-robin approach to line
56
 * use is employed. TODO is LRU scheme instead of round robin.
57 412 julius
 *
58 479 julius
 * The cache is a macro generated by Xilinx's IP generation tool. This is
59
 * because memories with dual-aspect ratios cannot be inferred via HDL.
60 412 julius
 *
61 479 julius
 * The size of lines, as set by the defines, controls how long each read
62
 * and write burst to/from the SDRAM is.
63 412 julius
 *
64 479 julius
 * There are two clock domains - the Wishbone and the DDR2 controller domain.
65 412 julius
 *
66 479 julius
 * A signal is sent to control logic in the DDR2 domain side to load and store
67
 * the contents of a particular line from and to the DDR2 controller's data
68
 * FIFOs. This loading and storing is done at the DDR2 clock domain's rate.
69 412 julius
 *
70 479 julius
 * The writing of address and control data is done from the Wishbone domain.
71
 *
72 412 julius
 * Multi-cycle paths:
73
 * Write:
74
 * To indicate that a writeback is occuring, a system-bus domain (wishbone, in
75
 * this case) signal is set, and then sampled in the controller domain whenever
76
 * a system-bus domain clock edge is detected. This register is "do_writeback"
77
 * and then the controller domain register "ddr2_write_done" is asserted when
78
 * the data has been written out of the RAMs and into the controller's fifos.
79
 * "ddr2_write_done" is then sampled by the system-bus domain and "do_writeback"
80
 * So there are paths between:
81
 * ( register -> (sampled by) -> register )
82 479 julius
 * wb_clk:do_writeback -> ddr2_clk:do_writeback_ddr2
83 412 julius
 * wb_clk:do_writeback -> ddr2_clk:ddr2_write_done
84
 * ddr2_clk:ddr2_write_done -> wb_clk:do_writeback
85
 *
86
 * Read:
87
 * The only signal crossing we have here is the one indicating the read data
88
 * has arrived into the cache RAM from the controller. The controller domain
89
 * register "ddr2_read_done" is set, and sampled in the system-bus domain by the
90
 * logic controlling the "do_readfrom" register. "ddr2_read_done" is cleared
91
 * when the controller domain sees that "do_readfrom" has been de-asserted.
92
 * So there are paths between:
93
 * ( register -> (sampled by) -> register )
94
 * ddr2_clk:ddr2_read_done -> wb_clk:do_readfrom
95
 * wb_clk:do_readfrom -> ddr2_clk:ddr2_read_done
96
 *
97 479 julius
*/
98 480 julius
module xilinx_ddr2_if (
99 412 julius
    input [31:0]       wb_adr_i,
100
    input              wb_stb_i,
101
    input              wb_cyc_i,
102 439 julius
    input [2:0]        wb_cti_i,
103
    input [1:0]        wb_bte_i,
104 412 julius
    input              wb_we_i,
105
    input [3:0]        wb_sel_i,
106
    input [31:0]       wb_dat_i,
107
    output [31:0]      wb_dat_o,
108
    output reg         wb_ack_o,
109 479 julius
 
110 412 julius
    output [12:0]      ddr2_a,
111
    output [1:0]       ddr2_ba,
112
    output             ddr2_ras_n,
113
    output             ddr2_cas_n,
114
    output             ddr2_we_n,
115
    output [1:0]       ddr2_cs_n,
116
    output [1:0]       ddr2_odt,
117
    output [1:0]       ddr2_cke,
118
    output [7:0]       ddr2_dm,
119
 
120
    inout [63:0]       ddr2_dq,
121
    inout [7:0]        ddr2_dqs,
122
    inout [7:0]        ddr2_dqs_n,
123
    output [1:0]       ddr2_ck,
124
    output [1:0]       ddr2_ck_n,
125 479 julius
 
126 412 julius
    input              ddr2_if_clk,
127 479 julius
    input              ddr2_if_rst,
128 412 julius
    input              idly_clk_200,
129 479 julius
 
130 412 julius
    input              wb_clk,
131
    input              wb_rst);
132
 
133
`include "xilinx_ddr2_params.v"
134
 
135 479 julius
   // Define to add a counter, signaling error if the controller locks up
136
   // (no ack after a certain period of time)
137
   //`define ERR_COUNTER
138
 
139
/*
140
`define DDR2_CACHE_NUM_LINES 16
141
`define DDR2_CACHE_NUM_LINES_ENC_WIDTH 4 // log2(`DDR2_CACHE_NUM_LINES)
142
 */
143
`define DDR2_CACHE_NUM_LINES 4
144
`define DDR2_CACHE_NUM_LINES_ENC_WIDTH 2 // log2(`DDR2_CACHE_NUM_LINES)
145
 
146
`define DDR2_CACHE_NUM_WORDS_PER_LINE 256
147
`define DDR2_CACHE_ADDR_WIDTH_WORDS_PER_LINE 8
148
`define DDR2_CACHE_TAG_ADDR_WIDTH (32-`DDR2_CACHE_ADDR_WIDTH_WORDS_PER_LINE-2)
149
 
150
`define DDR2_CACHE_DDR2_SIDE_NUM_WORDS_PER_LINE (`DDR2_CACHE_NUM_WORDS_PER_LINE/4)
151
`define DDR2_CACHE_DDR2_SIDE_ADDR_WIDTH_NUM_WORDS_PER_LINE (`DDR2_CACHE_ADDR_WIDTH_WORDS_PER_LINE - 2)
152
`define DDR2_CACHE_DDR2_SIDE_ADDR_WIDTH (`DDR2_CACHE_NUM_LINES_ENC_WIDTH + `DDR2_CACHE_DDR2_SIDE_ADDR_WIDTH_NUM_WORDS_PER_LINE)
153
 
154
`define DDR2_CACHE_TAG_BITS 31:(`DDR2_CACHE_ADDR_WIDTH_WORDS_PER_LINE+2)
155
 
156 412 julius
   wire                ddr2_clk; // DDR2 iface domain clock.
157
   wire                ddr2_rst; // reset from the ddr2 module
158
 
159
   wire                wb_req;
160
   reg                 wb_req_r;
161
   reg                 wb_ack_o_r;
162
 
163
   wire                wb_req_new;
164
   reg                 wb_req_new_r;
165
 
166 479 julius
   wire                wb_req_addr_hit;
167 412 julius
 
168 479 julius
   wire                cached_addr_valid;
169 412 julius
 
170 479 julius
 
171
   wire [31:(32 -`DDR2_CACHE_TAG_ADDR_WIDTH)] cached_addr;
172 412 julius
 
173 479 julius
`define DDR2_BURST_8_DQ64_ADDR_WIDTH 4 // = log2(burst of 8 64-bits = 16 words)
174
`define DDR2_BURST_4_DQ64_ADDR_WIDTH 3 // = log2(burst of 4 64-bits = 8 words)
175
   // This counts how many addresses we should write to the fifo - the number 
176
   // of discrete FIFO transactions.
177
   reg [`DDR2_CACHE_ADDR_WIDTH_WORDS_PER_LINE-`DDR2_BURST_8_DQ64_ADDR_WIDTH - 1:0] addr_counter;
178
 
179
   wire                cache_write;
180
 
181 412 julius
   wire                cache_hit;
182
 
183
   wire                wb_cache_en;
184
 
185
   reg                 do_writeback, do_writeback_r;
186
   wire                do_writeback_start, do_writeback_finished;
187 479 julius
   // Wire to indicate writing to data FIFO of MIG has completed
188
   wire                do_writeback_data_finished;
189
   // Wire to indicate that address FIFO of MIG should be written to to 
190
   // initiate memory accesses.
191
   reg                 do_writeback_addresses, do_writeback_addresses_r;
192
 
193 412 julius
   reg                 do_readfrom, do_readfrom_r;
194
   wire                do_readfrom_start, do_readfrom_finished;
195
   wire                doing_readfrom;
196
 
197 479 julius
   reg                 do_af_write;
198 412 julius
 
199
   // Domain crossing logic
200
   reg                 wb_clk_r;
201
   reg                 wb_clk_in_ddr2_clk;
202
 
203
   reg                 wb_clk_in_ddr2_clk_r;
204
   wire                wb_clk_edge;
205
   reg [2:0]            ddr2_clk_phase;
206
   // Sample when clk phase is 0
207 479 julius
   reg                 do_writeback_ddr2;
208 412 julius
   reg                 do_writeback_ddr2_fifo_we;
209
   reg                 ddr2_write_done;
210 479 julius
   reg [`DDR2_CACHE_DDR2_SIDE_ADDR_WIDTH_NUM_WORDS_PER_LINE - 1:0] ddr2_cache_line_word_addr;
211 412 julius
   wire [127:0]        ddr2_cache_data_o;
212
   reg                 rd_data_valid_r;
213
   reg                 ddr2_read_done;
214
 
215
   // DDR2 MIG interface wires
216
   wire                app_af_afull;
217
   wire                app_wdf_afull;
218
   wire                app_wdf_wren;
219
   wire                app_af_wren;
220 479 julius
   wire [30:0]          writeback_af_addr;
221
   wire [30:0]          readfrom_af_addr;
222 412 julius
   wire [30:0]          app_af_addr;
223
   wire [2:0]           app_af_cmd;
224 479 julius
 
225 412 julius
   wire [(APPDATA_WIDTH)-1:0] app_wdf_data;
226
   wire [(APPDATA_WIDTH/8)-1:0] app_wdf_mask_data;
227
   wire                         rd_data_valid;
228
   wire [(APPDATA_WIDTH)-1:0]    rd_data_fifo_out;
229
   wire                         phy_init_done;
230
 
231 479 julius
   wire [`DDR2_CACHE_NUM_LINES - 1 :0]   cache_line_addr_validate;
232
   wire [`DDR2_CACHE_NUM_LINES - 1 :0]   cache_line_addr_invalidate;
233
   wire [`DDR2_CACHE_NUM_LINES - 1 :0]   cache_line_addr_valid;
234
   wire [`DDR2_CACHE_NUM_LINES - 1 :0]   cache_line_hit;
235
   wire [`DDR2_CACHE_TAG_BITS]  cache_line_addr [0:`DDR2_CACHE_NUM_LINES-1] ;
236
 
237
   // Cache control signals
238
   // Wishbone side
239
   wire [`DDR2_CACHE_ADDR_WIDTH_WORDS_PER_LINE-1:0] wb_cache_adr;
240
   wire [3:0]                    wb_cache_sel_we;
241
   // DDR side
242
   wire                         ddr2_cache_en;
243
   wire [15:0]                   ddr2_cache_we;
244
 
245
   reg                          wb_bursting; // Indicate if burst is enabled
246
   reg [3:0]                     wb_burst_addr; // Burst counter, up to 16
247
   wire [1:0]                    wb_burst_addr_4beat;
248
   wire [2:0]                    wb_burst_addr_8beat;
249
   wire                         wb_burst_addr_incr;
250
   wire                         ack_err;
251
   reg                          ack_err_r;
252
 
253 480 julius
 
254
   // Synchronisation signals
255
   reg                          sync, sync_r;
256
   wire                         sync_start;
257
   wire                         sync_done;
258
 
259 479 julius
   // Decoded select line
260
   wire [`DDR2_CACHE_NUM_LINES-1:0] selected_cache_line;
261
   wire [`DDR2_CACHE_NUM_LINES_ENC_WIDTH-1:0] selected_cache_line_enc;
262
   reg [`DDR2_CACHE_NUM_LINES_ENC_WIDTH-1:0] selected_cache_line_enc_ddr2_clk;
263
 
264
   genvar                                     i;
265
   generate
266
      for (i=0;i<`DDR2_CACHE_NUM_LINES;i=i+1) begin : cache_addr
267
         xilinx_ddr2_wb_if_cache_adr_reg cache_addr_reg_inst
268
           ( .adr_i(wb_adr_i[`DDR2_CACHE_TAG_BITS]),
269
             .validate(cache_line_addr_validate[i]),
270
             .invalidate(cache_line_addr_invalidate[i]),
271
             .cache_hit(cache_line_hit[i]),
272
             .adr_valid(cache_line_addr_valid[i]),
273
             .cached_adr_o(cache_line_addr[i]),
274
             .clk(wb_clk),
275
             .rst(wb_rst));
276
      end
277
   endgenerate
278
 
279
   wire start_writeback, start_fill;
280
 
281
   xilinx_ddr2_wb_if_cache_control xilinx_ddr2_wb_if_cache_control0
282
     (
283
      // Outputs
284
      .start_writeback                  (start_writeback),
285
      .start_fill                       (start_fill),
286
      .cache_line_validate              (cache_line_addr_validate),
287
      .cache_line_invalidate            (cache_line_addr_invalidate),
288
      .selected_cache_line              (selected_cache_line),
289
      .selected_cache_line_enc          (selected_cache_line_enc),
290 480 julius
      .sync_done                        (sync_done),
291 479 julius
      // Inputs
292
      .cache_line_addr_valid            (cache_line_addr_valid),
293
      .cache_line_addr_hit              (cache_line_hit),
294
      .wb_req                           (wb_req),
295
      .cache_write                      (cache_write),
296
      .writeback_done                   (do_writeback_finished),
297
      .fill_done                        (do_readfrom_finished),
298 480 julius
      .sync_start                       (sync_start),
299 479 julius
      .wb_clk                           (wb_clk),
300
      .wb_rst                           (wb_rst));
301
 
302
   defparam xilinx_ddr2_wb_if_cache_control0.num_lines = `DDR2_CACHE_NUM_LINES;
303
   defparam xilinx_ddr2_wb_if_cache_control0.num_lines_log2 = `DDR2_CACHE_NUM_LINES_ENC_WIDTH;
304
 
305
   assign cached_addr = selected_cache_line[0] ? cache_line_addr[0] :
306
                        selected_cache_line[1] ? cache_line_addr[1] :
307
                        selected_cache_line[2] ? cache_line_addr[2] :
308
                        selected_cache_line[3] ? cache_line_addr[3] : 0;
309
 
310
   assign cache_write = wb_req & wb_we_i & wb_ack_o;
311
 
312
   assign cache_hit = |(selected_cache_line & cache_line_hit);
313
 
314
   assign cached_addr_valid = |(selected_cache_line & cache_line_addr_valid);
315
 
316
   assign wb_req_addr_hit = (wb_req & cache_hit & cached_addr_valid);
317
 
318 412 julius
   // Wishbone request detection
319 480 julius
   assign wb_req = wb_stb_i & wb_cyc_i & phy_init_done & !sync;
320 412 julius
 
321
   always @(posedge wb_clk)
322
     wb_req_r <= wb_req;
323
 
324
   assign wb_req_new = wb_req & !wb_req_r;
325 479 julius
 
326 412 julius
   always @(posedge wb_clk)
327
     wb_req_new_r <= wb_req_new;
328 479 julius
 
329
   always @(posedge wb_clk)
330
     if (wb_rst)
331
       wb_bursting <= 0;
332
   // Reset if acking end of transfer
333
     else if (wb_ack_o && wb_cti_i == 3'b111)
334
       wb_bursting <= 0;
335
   // Set if beginning new transaction and incrementing burst indicated
336
   // TODO - double check if this burst is going to go over a cache line
337
   // boundary - if so don't allow burst, fall back to classic cycles.
338
     else if (wb_req_new)
339
       wb_bursting <= (wb_cti_i == 3'b010);
340
 
341
   // Help constrain additions to appropriate bit-width for wrapping
342
   assign wb_burst_addr_4beat = wb_adr_i[3:2] + 1;
343
   assign wb_burst_addr_8beat = wb_adr_i[4:2] + 1;
344 412 julius
 
345 479 julius
   // Increment burst address whenever we get a hit when reading, or
346
   // when acking and writing.
347
   assign wb_burst_addr_incr = (wb_req_addr_hit & (!wb_we_i |
348
                                                (wb_we_i & wb_ack_o)));
349
 
350
   // Calculate burst address depending on burst type indicator
351 412 julius
   always @(posedge wb_clk)
352
     if (wb_rst)
353 479 julius
       wb_burst_addr <= 0;
354
     else if (wb_req_new)
355
       // When we have a bursting read to an address which is in cache then
356
       // initialise the address to the next word in the burst sequence.
357
       // If it's a miss, or it's a write, then we just take what's on the
358
       // bus.
359
       wb_burst_addr <= !(wb_req_addr_hit & !wb_we_i) ? wb_adr_i[5:2] :
360
                    wb_bte_i==2'b01 ? {wb_adr_i[5:4], wb_burst_addr_4beat }:
361
                    wb_bte_i==2'b10 ? {wb_adr_i[5], wb_burst_addr_8beat }:
362
                    wb_bte_i==2'b11 ? wb_adr_i[5:2] + 1 :
363
                    wb_adr_i[5:2];
364
     else if (wb_burst_addr_incr & wb_bte_i==2'b01)
365
       wb_burst_addr[1:0] <= wb_burst_addr[1:0] + 1;
366
     else if (wb_burst_addr_incr & wb_bte_i==2'b10)
367
       wb_burst_addr[2:0] <= wb_burst_addr[2:0] + 1;
368
     else if (wb_burst_addr_incr & wb_bte_i==2'b11)
369
       wb_burst_addr[3:0] <= wb_burst_addr[3:0] + 1;
370 412 julius
 
371 479 julius
`ifdef ERR_COUNTER
372
   reg [26:0] ack_err_cntr;
373
 
374 412 julius
   always @(posedge wb_clk)
375
     if (wb_rst)
376 479 julius
       ack_err_cntr <= 0;
377
     else if (!wb_req)
378
       ack_err_cntr <= 0;
379
     else if (|ack_err_cntr)
380
       ack_err_cntr <= ack_err_cntr + 1;
381
     else if (wb_req_new & !(|ack_err_cntr))
382
       ack_err_cntr <= 1;
383
 
384
   assign ack_err = (&ack_err_cntr);
385
 
386
   always @(posedge wb_clk)
387
     ack_err_r <= ack_err;
388
 
389
   assign wb_err_o = ack_err_r;
390
 
391
`else // !`ifdef ERR_COUNTER
392
 
393
   assign ack_err = 0;
394
   always @(posedge wb_clk)
395
     ack_err_r <= 0;
396
 
397
   assign wb_err_o = 0;
398
 
399
`endif
400
 
401
   always @(posedge wb_clk)
402
     if (wb_rst)
403 412 julius
       wb_ack_o <= 0;
404
     else
405 479 julius
       wb_ack_o <= wb_req_addr_hit &
406
                   (
407
                    // Simple acks on classic cycles
408
                    (!wb_bursting && !wb_ack_o && !wb_ack_o_r)
409
                    // De-assert ack when we see the final transaction
410
                    || (wb_bursting && !(wb_cti_i==3'b111))
411
                    );
412 412 julius
 
413
   always @(posedge wb_clk)
414
     wb_ack_o_r <= wb_ack_o;
415
 
416 480 julius
   // Logic controling synchronisation
417
   always @(posedge wb_clk)
418
     if (wb_rst)
419
       sync <= 0;
420
     else if (sync_done) // Sync. done indicator from cache controller
421
       sync <= 0;
422
 
423
   always @(posedge wb_clk)
424
     sync_r <= sync;
425
 
426
   assign sync_start = sync & !sync_r;
427
 
428
   task do_sync;
429
      begin
430
         // Wait for us to not be doing a transaction.
431
         while(wb_req)
432
           @wb_clk;
433
         // Cache not busy, initiate sync.
434
         sync = 1;
435
      end
436
   endtask // do_sync
437
 
438 479 julius
   // Writeback/readfrom lower address generation
439 412 julius
   always @(posedge wb_clk)
440
     if (wb_rst)
441 479 julius
       addr_counter <= 0;
442
     else if (app_af_wren)
443
       addr_counter <= addr_counter+1;
444 412 julius
 
445 479 julius
   // Determine if we're writing access requests into DDR2 interface AF
446 412 julius
   always @(posedge wb_clk)
447
     if (wb_rst)
448 479 julius
       do_af_write <= 0;
449
     else if (do_readfrom_start | do_writeback_data_finished)
450
       do_af_write <= 1;
451
     else if ((&addr_counter)) // Stop when counter rolls over
452
       do_af_write <= 0;
453 412 julius
 
454 479 julius
   // Wishbone side of cache enable. Always enabled unless doing DDR2-side
455
   // things (fill or writeback).
456
   assign wb_cache_en = !(do_readfrom | do_writeback);
457 412 julius
 
458 479 julius
 
459 412 julius
   // Writeback detect logic
460
   always @(posedge wb_clk)
461
     if (wb_rst)
462
       do_writeback <= 0;
463
     else if (ddr2_write_done) // DDR2 domain signal
464
       do_writeback <= 0;
465 479 julius
     else if (start_writeback)
466 412 julius
       do_writeback <= 1;
467 479 julius
 
468 412 julius
   always @(posedge wb_clk)
469
     do_writeback_r <= do_writeback;
470 479 julius
 
471
   // Detect falling edge of do_writeback
472
   assign do_writeback_data_finished = !do_writeback & do_writeback_r;
473 412 julius
 
474 479 julius
   always @(posedge wb_clk)
475
     if (wb_rst)
476
       do_writeback_addresses <= 0;
477
     else if (do_writeback_data_finished)
478
       do_writeback_addresses <= 1;
479
     else if ((&addr_counter))
480
       do_writeback_addresses <= 0;
481
 
482
   always @(posedge wb_clk)
483
     do_writeback_addresses_r <= do_writeback_addresses;
484
 
485
   // Detect rising edge of do_writeback
486 412 julius
   assign do_writeback_start = do_writeback & !do_writeback_r;
487 479 julius
   // Detect falling edge of address writing control signal
488
   assign do_writeback_finished = !do_writeback_addresses &
489
                                  do_writeback_addresses_r;
490
 
491 412 julius
   // DDR2 Read detect logic
492
   always @(posedge wb_clk)
493
     if (wb_rst)
494
       do_readfrom <= 0;
495
     else if (ddr2_read_done) // DDR2 domain signal
496
       do_readfrom <= 0;
497 479 julius
     else if (start_fill)
498 412 julius
       do_readfrom <= 1;
499
 
500
   always @(posedge wb_clk)
501
     do_readfrom_r <= do_readfrom;
502
 
503 479 julius
   // Detect line fill request rising edge
504 412 julius
   assign do_readfrom_start = do_readfrom & !do_readfrom_r;
505 479 julius
   // Detect line fill request falling edge
506 412 julius
   assign do_readfrom_finished = !do_readfrom & do_readfrom_r;
507
   assign doing_readfrom = do_readfrom | do_readfrom_r;
508
 
509
   // Address fifo signals
510 479 julius
   assign app_af_wren = (do_readfrom_r | do_writeback_addresses_r) &
511
                        !app_af_afull & do_af_write ;
512
   assign app_af_cmd[0] = do_readfrom; // 1 - read, 0 - write
513 412 julius
   assign app_af_cmd[2:1] = 0;
514 479 julius
 
515
   assign writeback_af_addr = {1'd0, cached_addr, addr_counter, 3'd0};
516 412 julius
 
517 479 julius
   assign readfrom_af_addr = {1'd0, wb_adr_i[`DDR2_CACHE_TAG_BITS],
518
                              addr_counter, 3'd0};
519
 
520
   assign app_af_addr = doing_readfrom ?  readfrom_af_addr : writeback_af_addr;
521 412 julius
   assign app_wdf_wren = do_writeback_ddr2_fifo_we;
522
   assign app_wdf_data = ddr2_cache_data_o;
523
   assign app_wdf_mask_data = 0;
524
 
525 479 julius
   always @(posedge wb_clk)
526
     if (wb_rst) wb_clk_r <= 0; else wb_clk_r <= ~wb_clk_r;
527 412 julius
   always @(posedge ddr2_clk) wb_clk_in_ddr2_clk <= wb_clk_r;
528
   always @(posedge ddr2_clk) wb_clk_in_ddr2_clk_r <= wb_clk_in_ddr2_clk;
529
 
530
   assign wb_clk_edge = wb_clk_in_ddr2_clk & !wb_clk_in_ddr2_clk_r;
531
 
532
   always @(posedge ddr2_clk)
533
     if (ddr2_rst)
534
       ddr2_clk_phase <= 0;
535
     else if (wb_clk_edge)
536
       ddr2_clk_phase <= 0;
537
     else
538
       ddr2_clk_phase <= ddr2_clk_phase + 1;
539
 
540
   always @(posedge ddr2_clk)
541
     if (ddr2_rst)
542 479 julius
       do_writeback_ddr2 <= 0;
543
     else if (&ddr2_cache_line_word_addr)
544
       do_writeback_ddr2 <= 0;
545
     else if (!(|ddr2_clk_phase) & do_writeback & // sample WB domain
546
              !ddr2_write_done)
547
       do_writeback_ddr2 <= 1;
548 412 julius
 
549
   always @(posedge ddr2_clk)
550 479 julius
     if (ddr2_rst)
551
       ddr2_cache_line_word_addr <= 0;
552
     else if (rd_data_valid | (do_writeback_ddr2 & !app_wdf_afull))
553
       ddr2_cache_line_word_addr <= ddr2_cache_line_word_addr + 1;
554
     else if (ddr2_write_done | ddr2_read_done)
555
       ddr2_cache_line_word_addr <= 0;
556
 
557
   always @(posedge ddr2_clk)
558
     do_writeback_ddr2_fifo_we <= (do_writeback_ddr2 & !app_wdf_afull);
559 412 julius
 
560
   always @(posedge ddr2_clk)
561
     if (ddr2_rst)
562
       ddr2_write_done <= 0;
563 479 julius
     else if ((&ddr2_cache_line_word_addr))
564 412 julius
       ddr2_write_done <= 1;
565
     else if ((!(|ddr2_clk_phase)) & !do_writeback) // sample WB domain
566
       ddr2_write_done <= 0;
567 479 julius
 
568 412 julius
   always @(posedge ddr2_clk)
569
     rd_data_valid_r <= rd_data_valid;
570
 
571
   // Read done signaling to WB domain
572
   always @(posedge ddr2_clk)
573
     if (ddr2_rst)
574
       ddr2_read_done <= 0;
575 479 julius
     else if (rd_data_valid_r & (&ddr2_cache_line_word_addr))
576 412 julius
       ddr2_read_done <= 1;
577
     else if (!(|ddr2_clk_phase) & !do_readfrom) // Read WB domain
578
       ddr2_read_done <= 0;
579
 
580 479 julius
   // Lower word address uses potentially bursting address counter
581
   assign wb_cache_adr = wb_bursting ?
582
       {wb_adr_i[(`DDR2_CACHE_ADDR_WIDTH_WORDS_PER_LINE+2)-1:6],wb_burst_addr}:
583
       wb_adr_i[(`DDR2_CACHE_ADDR_WIDTH_WORDS_PER_LINE+2)-1:2];
584
 
585
   assign wb_cache_sel_we = {4{wb_we_i & wb_ack_o}} & wb_sel_i;
586
   assign ddr2_cache_en = (rd_data_valid |do_writeback_ddr2);
587 412 julius
   assign ddr2_cache_we = {16{rd_data_valid}};
588 479 julius
 
589
   always @(posedge ddr2_clk)
590
     if (!(|ddr2_clk_phase)) // Read WB domain 
591
       selected_cache_line_enc_ddr2_clk <= selected_cache_line_enc;
592 412 julius
 
593
 
594 479 julius
 
595
   // Xilinx Coregen true dual-port RAMB
596 412 julius
   // Wishbone side : 32-bit
597
   // DDR2 side : 128-bit
598
   xilinx_ddr2_if_cache cache_mem0
599
     (
600
      // Wishbone side
601
      .clka(wb_clk),
602
      .ena(wb_cache_en),
603
      .wea(wb_cache_sel_we),
604 479 julius
      .addra({2'd0, selected_cache_line_enc,wb_cache_adr}),
605 412 julius
      .dina(wb_dat_i),
606
      .douta(wb_dat_o),
607
 
608
      // DDR2 controller side
609
      .clkb(ddr2_clk),
610
      .enb(ddr2_cache_en),
611
      .web(ddr2_cache_we),
612 479 julius
      .addrb({2'd0, selected_cache_line_enc_ddr2_clk,
613
              ddr2_cache_line_word_addr}),
614 412 julius
      .dinb(rd_data_fifo_out),
615
      .doutb(ddr2_cache_data_o));
616 479 julius
 
617 412 julius
   ddr2_mig #
618
     (
619 479 julius
     .BANK_WIDTH            (BANK_WIDTH),
620
     .CKE_WIDTH             (CKE_WIDTH),
621
     .CLK_WIDTH             (CLK_WIDTH),
622
     .COL_WIDTH             (COL_WIDTH),
623
     .CS_NUM                (CS_NUM),
624
     .CS_WIDTH              (CS_WIDTH),
625
     .CS_BITS               (CS_BITS),
626
     .DM_WIDTH                     (DM_WIDTH),
627
     .DQ_WIDTH              (DQ_WIDTH),
628
     .DQ_PER_DQS            (DQ_PER_DQS),
629
     .DQ_BITS               (DQ_BITS),
630
     .DQS_WIDTH             (DQS_WIDTH),
631
     .DQS_BITS              (DQS_BITS),
632
     .HIGH_PERFORMANCE_MODE (HIGH_PERFORMANCE_MODE),
633
     .ODT_WIDTH             (ODT_WIDTH),
634
     .ROW_WIDTH             (ROW_WIDTH),
635
     .APPDATA_WIDTH         (APPDATA_WIDTH),
636
     .ADDITIVE_LAT          (ADDITIVE_LAT),
637
     .BURST_LEN             (BURST_LEN),
638
     .BURST_TYPE            (BURST_TYPE),
639
     .CAS_LAT               (CAS_LAT),
640
     .ECC_ENABLE            (ECC_ENABLE),
641
     .MULTI_BANK_EN         (MULTI_BANK_EN),
642
     .ODT_TYPE              (ODT_TYPE),
643
     .REDUCE_DRV            (REDUCE_DRV),
644
     .REG_ENABLE            (REG_ENABLE),
645
     .TREFI_NS              (TREFI_NS),
646
     .TRAS                  (TRAS),
647
     .TRCD                  (TRCD),
648
     .TRFC                  (TRFC),
649
     .TRP                   (TRP),
650
     .TRTP                  (TRTP),
651
     .TWR                   (TWR),
652
     .TWTR                  (TWTR),
653
     .SIM_ONLY              (SIM_ONLY),
654
     .RST_ACT_LOW           (RST_ACT_LOW),
655
     .CLK_TYPE                     (CLK_TYPE),
656
     .DLL_FREQ_MODE                (DLL_FREQ_MODE),
657
     .CLK_PERIOD            (CLK_PERIOD)
658
       )
659 412 julius
   ddr2_mig0
660
     (
661 479 julius
     .sys_clk           (ddr2_if_clk),
662
     .idly_clk_200      (idly_clk_200),
663
     .sys_rst_n         (ddr2_if_rst),
664
     .ddr2_ras_n        (ddr2_ras_n),
665
     .ddr2_cas_n        (ddr2_cas_n),
666
     .ddr2_we_n         (ddr2_we_n),
667
     .ddr2_cs_n         (ddr2_cs_n),
668
     .ddr2_cke          (ddr2_cke),
669
     .ddr2_odt          (ddr2_odt),
670
     .ddr2_dm           (ddr2_dm),
671
     .ddr2_dq           (ddr2_dq),
672
     .ddr2_dqs          (ddr2_dqs),
673
     .ddr2_dqs_n        (ddr2_dqs_n),
674
     .ddr2_ck           (ddr2_ck),
675
     .ddr2_ck_n         (ddr2_ck_n),
676
     .ddr2_ba           (ddr2_ba),
677
     .ddr2_a            (ddr2_a),
678
 
679 412 julius
      .clk0_tb           (ddr2_clk),
680
      .rst0_tb           (ddr2_rst),
681 479 julius
      .usr_clk (wb_clk),
682
     .app_af_afull      (app_af_afull),
683
     .app_wdf_afull     (app_wdf_afull),
684
     .rd_data_valid     (rd_data_valid),
685
     .rd_data_fifo_out  (rd_data_fifo_out),
686
     .app_af_wren       (app_af_wren),
687
     .app_af_cmd        (app_af_cmd),
688
     .app_af_addr       (app_af_addr),
689
     .app_wdf_wren      (app_wdf_wren),
690
     .app_wdf_data      (app_wdf_data),
691
     .app_wdf_mask_data (app_wdf_mask_data),
692
     .phy_init_done     (phy_init_done)
693 412 julius
      );
694 479 julius
 
695 412 julius
 
696 479 julius
endmodule // xilinx_ddr2_if2
697
 
698 412 julius
// Local Variables:
699
// verilog-library-directories:("." "ddr2_mig")
700
// verilog-library-extensions:(".v" ".h")
701
// End:
702 479 julius
 
703
 
704
module xilinx_ddr2_wb_if_cache_adr_reg
705
  (adr_i, validate, invalidate,
706
   cached_adr_o, cache_hit, adr_valid,
707
   clk, rst);
708
 
709
   parameter full_adr_width = 32;
710
   parameter word_adr_width = 2; // 4 bytes per word   
711
   parameter line_adr_width = 8; // 256 words per "line"
712
 
713
   parameter tag_width = full_adr_width - line_adr_width - word_adr_width;
714
 
715
 
716
   input [full_adr_width-1: word_adr_width + line_adr_width] adr_i;
717
   input                 validate;
718
   input                 invalidate;
719
   output [full_adr_width-1: word_adr_width + line_adr_width] cached_adr_o;
720
   output                 cache_hit;
721
   output reg             adr_valid;
722
 
723
   input                  clk, rst;
724
 
725
   reg [tag_width-1:0]     cached_adr;
726
 
727
   assign cached_adr_o = cached_adr;
728
 
729
   always @(posedge clk)
730
     if (rst)
731
       cached_adr <= 0;
732
     else if (validate)
733
       cached_adr <= adr_i;
734
 
735
   always @(posedge clk)
736
     if (rst)
737
       adr_valid <= 0;
738
     else if (validate)
739
       adr_valid <= 1;
740
     else if (invalidate)
741
       adr_valid <= 0;
742
 
743
   assign cache_hit = (adr_i == cached_adr);
744
 
745
endmodule // xilinx_ddr2_wb_if_cache_adr_reg
746
 
747
module xilinx_ddr2_wb_if_cache_control
748 480 julius
  ( cache_line_addr_valid, cache_line_addr_hit,
749 479 julius
    wb_req,
750
    cache_write,
751 480 julius
    writeback_done, fill_done,
752
    sync_start, sync_done,
753 479 julius
    start_writeback, start_fill,
754
    cache_line_validate, cache_line_invalidate,
755
    selected_cache_line, selected_cache_line_enc,
756
    wb_clk, wb_rst);
757
 
758
   parameter num_lines = 16;
759
   parameter num_lines_log2 = 4;
760
 
761
   input [num_lines-1:0] cache_line_addr_valid;
762
   input [num_lines-1:0] cache_line_addr_hit;
763
 
764
   input                 wb_req;
765
   input                 cache_write;
766
   input                 writeback_done, fill_done;
767 480 julius
 
768
   input                 sync_start;
769
   output                sync_done;
770 479 julius
 
771
   output reg            start_writeback;
772
   output reg            start_fill;
773
   output reg [num_lines-1:0] cache_line_validate;
774
   output reg [num_lines-1:0] cache_line_invalidate;
775 480 julius
 
776
   output [num_lines-1:0]     selected_cache_line;
777 479 julius
   output reg [num_lines_log2-1:0] selected_cache_line_enc;
778
 
779 480 julius
   input                           wb_clk, wb_rst;
780 479 julius
 
781 480 julius
   reg [num_lines-1:0]              lines_dirty;
782 479 julius
 
783 480 julius
   reg [num_lines-1:0]              selected_cache_line_from_miss;
784 479 julius
 
785 480 julius
   reg                             selected_cache_line_new;
786 479 julius
 
787 480 julius
   reg                             invalidate_clean_line;
788
 
789
   reg [num_lines-1:0]              selected_cache_line_r;
790
   reg [num_lines-1:0]              selected_cache_line_r2;
791
 
792
   reg                             wb_req_r;
793
 
794
   wire                            wb_req_new;
795
   reg                             wb_req_new_r;
796
 
797
   parameter sync_line_check_wait = 4;
798
   reg [num_lines-1:0]              sync_line_counter;
799
   reg                             sync_doing;
800
   reg [sync_line_check_wait-1:0]  sync_line_select_wait_counter_shr;
801
   reg                             sync_line_done;
802
   wire                            sync_writeback_line;
803 479 julius
 
804
 
805
   always @(posedge wb_clk)
806
     wb_req_r <= wb_req;
807
 
808
   assign wb_req_new = wb_req & !wb_req_r;
809
 
810
   always @(posedge wb_clk)
811
     wb_req_new_r <= wb_req_new;
812
 
813
   // Select a cache line when we miss. Currently very simply is round robin
814
   always @(posedge wb_clk)
815
     if (wb_rst)
816
       selected_cache_line_from_miss <= 1;
817
     else if (wb_req_new_r & !(|selected_cache_line_r)) // miss,no line selected
818
       // Shift select bit one
819
       selected_cache_line_from_miss
820
         <= {selected_cache_line_from_miss[num_lines-2:0],
821
             selected_cache_line_from_miss[num_lines-1]};
822
 
823
 
824
   // Line selection logic, when line address is valid and hit, we select
825
   always @(posedge wb_clk)
826
     if (wb_rst)
827
       selected_cache_line_r <= 0;
828
     else if (wb_req_new)
829
       selected_cache_line_r <= cache_line_addr_valid & cache_line_addr_hit;
830
     else if (wb_req_new_r & !(|selected_cache_line_r))
831
       selected_cache_line_r <= selected_cache_line_from_miss;
832 480 julius
     else if (sync_doing)
833
       selected_cache_line_r <= sync_line_counter;
834 479 julius
 
835
   always @(posedge wb_clk)
836
     selected_cache_line_r2 <= selected_cache_line_r;
837
 
838
   assign selected_cache_line = selected_cache_line_r2;
839
 
840
   // A new line of cache has been selected
841
   always @(posedge wb_clk)
842
     if (wb_rst)
843
       selected_cache_line_new <= 0;
844
     else if (wb_req_new & (&(cache_line_addr_valid & cache_line_addr_hit)))
845
       // New line address selected
846
       selected_cache_line_new <= 1;
847
     else if ((!selected_cache_line_new) & wb_req_new_r)
848
       // Didn't select one last time, so we must have forced ourselves to 
849
       // select a new one
850
       selected_cache_line_new <= 1;
851
     else if (selected_cache_line_new)
852
       selected_cache_line_new <= 0;
853
 
854
   always @(posedge wb_clk)
855
     if (wb_rst)
856 480 julius
       lines_dirty <= 0;
857 479 julius
     else if (cache_write)
858 480 julius
       lines_dirty <= lines_dirty | selected_cache_line_r;
859 479 julius
     else if (writeback_done)
860 480 julius
       lines_dirty <= lines_dirty & ~(selected_cache_line_r);
861 479 julius
 
862
   // Validate the cache line address in the register when line filled
863
   always @(posedge wb_clk)
864
     if (wb_rst)
865
       cache_line_validate <= 0;
866
     else if (fill_done)
867
       cache_line_validate <= selected_cache_line_r;
868
     else if (|cache_line_validate)
869
       cache_line_validate <= 0;
870
 
871
   // Invalidate the cache line address in the register when line written back
872
   always @(posedge wb_clk)
873
     if (wb_rst)
874
       cache_line_invalidate <= 0;
875 480 julius
     else if ((writeback_done & !sync_doing) | invalidate_clean_line)
876 479 julius
       cache_line_invalidate <= selected_cache_line_r;
877
     else if (|cache_line_invalidate)
878
       cache_line_invalidate <= 0;
879
 
880
   // Initiate-writeback logic
881
   always @(posedge wb_clk)
882
     if (wb_rst)
883
       start_writeback <= 0;
884 480 julius
     else if (start_writeback)
885
       start_writeback <= 0;
886
     else if (selected_cache_line_new &
887
              (|(lines_dirty & selected_cache_line_r)) &
888 479 julius
              (|(selected_cache_line_r & cache_line_addr_valid)) &
889
              !(|(cache_line_addr_hit & selected_cache_line_r)))
890
       start_writeback <= 1;
891 480 julius
     else if (sync_writeback_line)
892
       start_writeback <= 1;
893 479 julius
 
894
   // Invalidate lines which we haven't written to so we can fill them
895
   always @(posedge wb_clk)
896
     if (wb_rst)
897
       invalidate_clean_line <= 0;
898
     else if (invalidate_clean_line)
899
       invalidate_clean_line <= 0;
900
     else if ((selected_cache_line_new) &  // New line selected
901 480 julius
              !(|(lines_dirty & selected_cache_line_r)) & // It's not dirty
902 479 julius
              // It's valid, but we've selected it so we're trashing it
903
              (|(selected_cache_line_r & cache_line_addr_valid)) &
904
              !(|(cache_line_addr_hit & selected_cache_line_r))) // Not a hit
905
       invalidate_clean_line <= 1;
906
 
907
   reg                    invalidate_clean_line_r;
908
   always @(posedge wb_clk)
909
     invalidate_clean_line_r <= invalidate_clean_line;
910
 
911
 
912
   // Initiate-fill logic
913
   always @(posedge wb_clk)
914
     if (wb_rst)
915
       start_fill <= 0;
916
     else if (((selected_cache_line_new) & // New line selected
917
               // not valid
918
               !(|(cache_line_addr_valid & selected_cache_line_r))) |
919 480 julius
              (writeback_done & !sync_doing) | invalidate_clean_line_r
920 479 julius
              )
921
       start_fill <= 1;
922
     else if (start_fill)
923
       start_fill <= 0;
924
 
925 480 julius
   // Hardcoded to 4 lines currently.
926 479 julius
   always @(posedge wb_clk)
927
     if (selected_cache_line_r[0])
928
       selected_cache_line_enc <= 0;
929
     else if (selected_cache_line_r[1])
930
       selected_cache_line_enc <= 1;
931
     else if (selected_cache_line_r[2])
932
       selected_cache_line_enc <= 2;
933
     else if (selected_cache_line_r[3])
934
       selected_cache_line_enc <= 3;
935
 
936
 
937 480 julius
   // Synchronisation control
938
 
939
   always @(posedge wb_clk)
940
     if (wb_rst)
941
       sync_doing <= 0;
942
     else if (sync_start)
943
       sync_doing <= 1;
944
     else if (sync_done)
945
       sync_doing <= 0;
946
 
947
   always @(posedge wb_clk)
948
     if (wb_rst)
949
       sync_line_counter <= 0;
950
     else if (sync_start)
951
       // Set first line to check
952
       sync_line_counter[0] <= 1'b1;
953
     else if (sync_line_done)
954
       // Shift along, check next line
955
       sync_line_counter <=  {sync_line_counter[num_lines-2:0], 1'b0};
956
 
957
   // Pulse this on finishing of checking lines
958
   assign sync_done = sync_line_counter[num_lines-1] & sync_line_done;
959
 
960
   // Pulses when a dirty line is detected and should be written back.
961
   assign sync_writeback_line = sync_doing &
962
                                sync_line_select_wait_counter_shr[0] &
963
                                cache_line_addr_valid &
964
                                |(sync_line_counter & lines_dirty);
965
 
966
   always @(posedge wb_clk)
967
     if (wb_rst)
968
       sync_line_select_wait_counter_shr <= 0;
969
     else if (|sync_line_select_wait_counter_shr)
970
       sync_line_select_wait_counter_shr
971
         <= {1'b0,sync_line_select_wait_counter_shr[sync_line_check_wait-1:1]};
972
     else if (sync_start | (sync_line_done & !sync_done))
973
       sync_line_select_wait_counter_shr[sync_line_check_wait-1] <= 1'b1;
974
 
975
   always @(posedge wb_clk)
976
     if (wb_rst)
977
       sync_line_done <= 1'b0;
978
     else if (sync_line_done)
979
       sync_line_done <= 1'b0;
980
   // Either line doesn't need writeback
981
     else if (sync_line_select_wait_counter_shr[0] & !sync_writeback_line)
982
       sync_line_done <= 1'b1;
983
   // Or writeback finished
984
     else if  (writeback_done & sync_doing)
985
       sync_line_done <= 1'b1;
986
 
987
 
988 479 julius
endmodule // xilinx_ddr2_wb_if_cache_control

powered by: WebSVN 2.1.0

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