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

Subversion Repositories amber

[/] [amber/] [trunk/] [hw/] [vlog/] [amber25/] [a25_dcache.v] - Blame information for rev 57

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

Line No. Rev Author Line
1 16 csantifort
//////////////////////////////////////////////////////////////////
2
//                                                              //
3 17 csantifort
//  L1 Data Cache for Amber 25 Core                             //
4 16 csantifort
//                                                              //
5
//  This file is part of the Amber project                      //
6
//  http://www.opencores.org/project,amber                      //
7
//                                                              //
8
//  Description                                                 //
9 17 csantifort
//  Synthesizable L1 Data Cache                                 //
10
//  Cache is 2, 3, 4 or 8 way, 256 line and 16 bytes per line.  //
11
//  The cache policy is write-through and                       //
12 16 csantifort
//  read allocate. For swap instructions (SWP and SWPB) the     //
13
//  location is evicted from the cache and read from main       //
14
//  memory.                                                     //
15
//                                                              //
16
//  Author(s):                                                  //
17
//      - Conor Santifort, csantifort.amber@gmail.com           //
18
//                                                              //
19
//////////////////////////////////////////////////////////////////
20
//                                                              //
21
// Copyright (C) 2011 Authors and OPENCORES.ORG                 //
22
//                                                              //
23
// This source file may be used and distributed without         //
24
// restriction provided that this copyright statement is not    //
25
// removed from the file and that any derivative work contains  //
26
// the original copyright notice and the associated disclaimer. //
27
//                                                              //
28
// This source file is free software; you can redistribute it   //
29
// and/or modify it under the terms of the GNU Lesser General   //
30
// Public License as published by the Free Software Foundation; //
31
// either version 2.1 of the License, or (at your option) any   //
32
// later version.                                               //
33
//                                                              //
34
// This source is distributed in the hope that it will be       //
35
// useful, but WITHOUT ANY WARRANTY; without even the implied   //
36
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
37
// PURPOSE.  See the GNU Lesser General Public License for more //
38
// details.                                                     //
39
//                                                              //
40
// You should have received a copy of the GNU Lesser General    //
41
// Public License along with this source; if not, download it   //
42
// from http://www.opencores.org/lgpl.shtml                     //
43
//                                                              //
44
//////////////////////////////////////////////////////////////////
45
 
46
`include "a25_config_defines.v"
47
 
48
module a25_dcache
49
#(
50
 
51
// ---------------------------------------------------------
52
// Cache Configuration
53
 
54
// Limited to Linux 4k page sizes -> 256 lines
55
parameter CACHE_LINES          = 256,
56
 
57
// This cannot be changed without some major surgeory on
58
// this module                                       
59
parameter CACHE_WORDS_PER_LINE = 4,
60
 
61
// Changing this parameter is the recommended
62
// way to change the overall cache size; 2, 4 and 8 ways are supported.
63
//   2 ways -> 8KB  cache
64
//   4 ways -> 16KB cache
65
//   8 ways -> 32KB cache
66
parameter WAYS              = `A25_DCACHE_WAYS ,
67
 
68
// derived configuration parameters
69
parameter CACHE_ADDR_WIDTH  = log2 ( CACHE_LINES ),                        // = 8
70
parameter WORD_SEL_WIDTH    = log2 ( CACHE_WORDS_PER_LINE ),               // = 2
71
parameter TAG_ADDR_WIDTH    = 32 - CACHE_ADDR_WIDTH - WORD_SEL_WIDTH - 2,  // = 20
72
parameter TAG_WIDTH         = TAG_ADDR_WIDTH + 1,                          // = 21, including Valid flag
73
parameter CACHE_LINE_WIDTH  = CACHE_WORDS_PER_LINE * 32,                   // = 128
74
parameter TAG_ADDR32_LSB    = CACHE_ADDR_WIDTH + WORD_SEL_WIDTH + 2,       // = 12
75
parameter CACHE_ADDR32_MSB  = CACHE_ADDR_WIDTH + WORD_SEL_WIDTH + 2 - 1,   // = 11
76
parameter CACHE_ADDR32_LSB  =                    WORD_SEL_WIDTH + 2    ,   // = 4
77
parameter WORD_SEL_MSB      = WORD_SEL_WIDTH + 2 - 1,                      // = 3
78
parameter WORD_SEL_LSB      =                  2                           // = 2
79
// ---------------------------------------------------------
80
)
81
 
82
 
83
(
84
input                               i_clk,
85
 
86
// Read / Write requests from core
87
input                               i_request,
88
input                               i_exclusive,        // exclusive access, part of swap instruction
89
input      [31:0]                   i_write_data,
90
input                               i_write_enable,     // write request from execute stage
91
input      [31:0]                   i_address,          // registered address from execute
92
input      [31:0]                   i_address_nxt,      // un-registered version of address from execute stage
93
input      [3:0]                    i_byte_enable,
94
input                               i_cache_enable,     // from co-processor 15 configuration register
95
input                               i_cache_flush,      // from co-processor 15 register
96
 
97
output      [31:0]                  o_read_data,
98
input                               i_fetch_stall,
99 35 csantifort
input                               i_exec_stall,
100 16 csantifort
output                              o_stall,
101
 
102
// WB Read Request                                                          
103 35 csantifort
output                              o_wb_cached_req,        // Read Request
104
input      [127:0]                  i_wb_cached_rdata,      // wb bus                              
105
input                               i_wb_cached_ready       // wb_stb && !wb_ack
106 16 csantifort
);
107
 
108
`include "a25_localparams.v"
109
`include "a25_functions.v"
110
 
111
// One-hot encoded
112
localparam       C_INIT   = 0,
113
                 C_CORE   = 1,
114
                 C_FILL   = 2,
115
                 C_INVA   = 3,
116
                 C_STATES = 4;
117
 
118
localparam [3:0] CS_INIT               = 4'd0,
119
                 CS_IDLE               = 4'd1,
120 39 csantifort
                 CS_FILL               = 4'd2,
121
                 CS_FILL_COMPLETE      = 4'd3,
122
                 CS_TURN_AROUND        = 4'd4,
123
                 CS_WRITE_HIT          = 4'd5,
124
                 CS_WRITE_HIT_WAIT_WB  = 4'd6,
125
                 CS_WRITE_MISS_WAIT_WB = 4'd7,
126
                 CS_EX_DELETE          = 4'd8;
127 16 csantifort
 
128
 
129
reg  [3:0]                  c_state    = CS_IDLE;
130
reg  [C_STATES-1:0]         source_sel = 1'd1 << C_CORE;
131
reg  [CACHE_ADDR_WIDTH:0]   init_count = 'd0;
132
 
133
wire [TAG_WIDTH-1:0]        tag_rdata_way [WAYS-1:0];
134
wire [CACHE_LINE_WIDTH-1:0] data_rdata_way[WAYS-1:0];
135
wire [WAYS-1:0]             data_wenable_way;
136
wire [WAYS-1:0]             data_hit_way;
137
reg  [WAYS-1:0]             data_hit_way_r = 'd0;
138
wire [WAYS-1:0]             tag_wenable_way;
139
reg  [WAYS-1:0]             select_way = 'd0;
140
wire [WAYS-1:0]             next_way;
141
reg  [WAYS-1:0]             valid_bits_r = 'd0;
142
 
143
reg  [3:0]                  random_num = 4'hf;
144
 
145
wire [CACHE_ADDR_WIDTH-1:0] tag_address;
146
wire [TAG_WIDTH-1:0]        tag_wdata;
147
wire                        tag_wenable;
148
 
149
wire [CACHE_LINE_WIDTH-1:0] read_miss_wdata;
150
wire [CACHE_LINE_WIDTH-1:0] write_hit_wdata;
151
reg  [CACHE_LINE_WIDTH-1:0] data_wdata_r = 'd0;
152
wire [CACHE_LINE_WIDTH-1:0] consecutive_write_wdata;
153
wire [CACHE_LINE_WIDTH-1:0] data_wdata;
154
wire [CACHE_ADDR_WIDTH-1:0] data_address;
155
wire [31:0]                 write_data_word;
156
 
157
wire                        idle_hit;
158
wire                        read_miss;
159
wire                        write_miss;
160
wire                        write_hit;
161
wire                        consecutive_write;
162
wire                        fill_state;
163
 
164
reg  [31:0]                 miss_address = 'd0;
165
wire [CACHE_LINE_WIDTH-1:0] hit_rdata;
166
 
167
wire                        read_stall;
168
wire                        write_stall;
169
wire                        cache_busy_stall;
170 35 csantifort
wire                        core_stall;
171 16 csantifort
wire                        write_state;
172
 
173
wire                        request_pulse;
174
wire                        request_hold;
175
reg                         request_r = 'd0;
176
wire [CACHE_ADDR_WIDTH-1:0] address;
177
reg  [CACHE_LINE_WIDTH-1:0] wb_rdata_burst = 'd0;
178
 
179
wire                        exclusive_access;
180
wire                        ex_read_hit;
181
reg                         ex_read_hit_r = 'd0;
182
reg  [WAYS-1:0]             ex_read_hit_way = 'd0;
183
reg  [CACHE_ADDR_WIDTH-1:0] ex_read_address;
184
wire                        ex_read_hit_clear;
185
wire                        ex_read_cache_busy;
186
 
187
reg  [31:0]                 wb_address = 'd0;
188
wire                        rbuf_hit = 'd0;
189
wire                        wb_hit;
190 35 csantifort
wire [127:0]                read_data128;
191 16 csantifort
genvar                      i;
192
 
193
// ======================================
194
// Address to use for cache access
195
// ======================================
196
// If currently stalled then the address for the next
197
// cycle will be the same as it is in the current cycle
198
//
199 35 csantifort
assign core_stall = i_fetch_stall || i_exec_stall || o_stall;
200 16 csantifort
 
201 35 csantifort
assign address = core_stall ? i_address    [CACHE_ADDR32_MSB:CACHE_ADDR32_LSB] :
202
                              i_address_nxt[CACHE_ADDR32_MSB:CACHE_ADDR32_LSB] ;
203 16 csantifort
 
204
// ======================================
205
// Outputs
206
// ======================================
207
 
208 35 csantifort
assign read_data128 = wb_hit ? i_wb_cached_rdata : hit_rdata;
209
 
210
assign o_read_data  = i_address[WORD_SEL_MSB:WORD_SEL_LSB] == 2'd0 ? read_data128 [31:0]   :
211
                      i_address[WORD_SEL_MSB:WORD_SEL_LSB] == 2'd1 ? read_data128 [63:32]  :
212
                      i_address[WORD_SEL_MSB:WORD_SEL_LSB] == 2'd2 ? read_data128 [95:64]  :
213
                                                                     read_data128 [127:96] ;
214
 
215 16 csantifort
// Don't allow the cache to stall the wb i/f for an exclusive access
216
// The cache needs a couple of cycles to flush a potential copy of the exclusive
217
// address, but the wb can do the access in parallel. So there is no
218
// stall in the state CS_EX_DELETE, even though the cache is out of action. 
219
// This works fine as long as the wb is stalling the core
220
assign o_stall         = request_hold && ( read_stall || write_stall || cache_busy_stall || ex_read_cache_busy );
221
 
222 35 csantifort
assign o_wb_cached_req = ( (read_miss || write_miss || write_hit) && c_state == CS_IDLE ) || consecutive_write;
223 16 csantifort
 
224
 
225
// ======================================
226
// Cache State Machine
227
// ======================================
228
 
229
// Little State Machine to Flush Tag RAMS
230
always @ ( posedge i_clk )
231
    if ( i_cache_flush )
232
        begin
233
        c_state     <= CS_INIT;
234
        source_sel  <= 1'd1 << C_INIT;
235
        init_count  <= 'd0;
236
        `ifdef A25_CACHE_DEBUG
237
        `TB_DEBUG_MESSAGE
238
        $display("Cache Flush");
239
        `endif
240
        end
241
    else
242
        case ( c_state )
243
            CS_INIT :
244
                if ( init_count < CACHE_LINES [CACHE_ADDR_WIDTH:0] )
245
                    begin
246
                    init_count  <= init_count + 1'd1;
247
                    source_sel  <= 1'd1 << C_INIT;
248
                    end
249
                else
250
                    begin
251
                    source_sel  <= 1'd1 << C_CORE;
252
                    c_state     <= CS_TURN_AROUND;
253
                    end
254
 
255
             CS_IDLE :
256
                begin
257
                source_sel  <= 1'd1 << C_CORE;
258
 
259
                if ( ex_read_hit || ex_read_hit_r )
260
                    begin
261
                    select_way  <= data_hit_way | ex_read_hit_way;
262
                    c_state     <= CS_EX_DELETE;
263
                    source_sel  <= 1'd1 << C_INVA;
264
                    end
265
                else if ( read_miss )
266 39 csantifort
                    c_state <= CS_FILL;
267 16 csantifort
                else if ( write_hit )
268
                    begin
269 35 csantifort
                    if ( i_wb_cached_ready )
270 39 csantifort
                        c_state <= CS_WRITE_HIT;
271 16 csantifort
                    else
272
                        c_state <= CS_WRITE_HIT_WAIT_WB;
273
                    end
274 35 csantifort
                else if ( write_miss && !i_wb_cached_ready )
275 16 csantifort
                        c_state <= CS_WRITE_MISS_WAIT_WB;
276
                end
277
 
278 35 csantifort
 
279 39 csantifort
             CS_FILL :
280 16 csantifort
                // third read of burst of 4
281
                // wb read request asserted, wait for ack
282 35 csantifort
                if ( i_wb_cached_ready )
283 16 csantifort
                    begin
284
                    c_state     <= CS_FILL_COMPLETE;
285
                    source_sel  <= 1'd1 << C_FILL;
286
 
287
                    // Pick a way to write the cache update into
288
                    // Either pick one of the invalid caches, or if all are valid, then pick
289
                    // one randomly
290
 
291
                    select_way  <= next_way;
292
                    random_num  <= {random_num[2], random_num[1], random_num[0],
293
                                     random_num[3]^random_num[2]};
294
                    end
295
 
296
 
297
             // Write the read fetch data in this cycle
298
             CS_FILL_COMPLETE :
299
                begin
300
                // Back to normal cache operations, but
301
                // use physical address for first read as
302
                // address moved before the stall was asserted for the read_miss
303
                // However don't use it if its a non-cached address!
304
                source_sel  <= 1'd1 << C_CORE;
305
                c_state     <= CS_TURN_AROUND;
306
                end
307
 
308
 
309
             // Ignore the tag read data in this cycle   
310
             // Wait 1 cycle to pre-read the cache and return to normal operation                 
311
             CS_TURN_AROUND :
312
                begin
313
                c_state     <= CS_IDLE;
314
                end
315
 
316
 
317
             // Flush the entry matching an exclusive access         
318
             CS_EX_DELETE:
319
                begin
320
                `ifdef A25_CACHE_DEBUG
321
                `TB_DEBUG_MESSAGE
322
                $display("Cache deleted Locked entry");
323
                `endif
324
                c_state    <= CS_TURN_AROUND;
325
                source_sel <= 1'd1 << C_CORE;
326
                end
327
 
328
 
329 39 csantifort
             CS_WRITE_HIT:
330 16 csantifort
                if ( !consecutive_write )
331
                    c_state     <= CS_IDLE;
332
 
333
 
334
             CS_WRITE_HIT_WAIT_WB:
335
                // wait for an ack on the wb bus to complete the write
336 35 csantifort
                if ( i_wb_cached_ready )
337 16 csantifort
                    c_state     <= CS_IDLE;
338
 
339
 
340
             CS_WRITE_MISS_WAIT_WB:
341
                // wait for an ack on the wb bus to complete the write
342 35 csantifort
                if ( i_wb_cached_ready )
343 16 csantifort
                    c_state     <= CS_IDLE;
344
 
345
        endcase
346
 
347
 
348
// ======================================
349
// Capture WB Block Read - burst of 4 words
350
// ======================================
351
always @ ( posedge i_clk )
352 35 csantifort
    if ( i_wb_cached_ready )
353
        wb_rdata_burst <= i_wb_cached_rdata;
354 16 csantifort
 
355
 
356
 
357
// ======================================
358
// Miss Address
359
// ======================================
360
always @ ( posedge i_clk )
361 35 csantifort
    if ( o_wb_cached_req || write_hit )
362 16 csantifort
        miss_address <= i_address;
363
 
364
always @ ( posedge i_clk )
365
    if ( write_hit )
366
        begin
367
        data_hit_way_r      <= data_hit_way;
368
        end
369
 
370
always @ ( posedge i_clk )
371
    if ( write_hit || consecutive_write )
372
        begin
373
        data_wdata_r   <= data_wdata;
374
        end
375
 
376
assign consecutive_write = miss_address[31:4] == i_address[31:4] &&
377
                           i_write_enable &&
378 39 csantifort
                           c_state == CS_WRITE_HIT &&
379 16 csantifort
                           request_pulse;
380
 
381
 
382
always @(posedge i_clk)
383 35 csantifort
    if ( o_wb_cached_req )
384 16 csantifort
        wb_address <= i_address;
385 35 csantifort
    else if ( i_wb_cached_ready && fill_state )
386 16 csantifort
        wb_address <= {wb_address[31:4], wb_address[3:2] + 1'd1, 2'd0};
387
 
388 39 csantifort
assign fill_state       = c_state == CS_FILL ;
389 35 csantifort
assign wb_hit           = i_address == wb_address && i_wb_cached_ready && fill_state;
390 16 csantifort
 
391
 
392
// ======================================
393
// Hold Requests
394
// ======================================
395
always @(posedge i_clk)
396
    request_r <= (request_pulse || request_r) && o_stall;
397
 
398
assign request_hold = request_pulse || request_r;
399
 
400
 
401
// ======================================
402
// Remember Read-Modify-Write Hit
403
// ======================================
404
assign ex_read_hit_clear = c_state == CS_EX_DELETE;
405
 
406
always @ ( posedge i_clk )
407
    if ( ex_read_hit_clear )
408
        begin
409
        ex_read_hit_r   <= 1'd0;
410
        ex_read_hit_way <= 'd0;
411
        end
412
    else if ( ex_read_hit )
413
        begin
414
 
415
        `ifdef A25_CACHE_DEBUG
416
            `TB_DEBUG_MESSAGE
417
            $display ("Exclusive access cache hit address 0x%08h", i_address);
418
        `endif
419
 
420
        ex_read_hit_r   <= 1'd1;
421
        ex_read_hit_way <= data_hit_way;
422
        end
423
    else if ( c_state == CS_FILL_COMPLETE && ex_read_hit_r )
424
        ex_read_hit_way <= select_way;
425
 
426
 
427
always @ (posedge i_clk)
428
    if ( ex_read_hit )
429
        ex_read_address <= i_address[CACHE_ADDR32_MSB:CACHE_ADDR32_LSB];
430
 
431
 
432
assign tag_address      = source_sel[C_FILL] ? miss_address      [CACHE_ADDR32_MSB:CACHE_ADDR32_LSB] :
433
                          source_sel[C_INVA] ? ex_read_address                                       :
434
                          source_sel[C_INIT] ? init_count[CACHE_ADDR_WIDTH-1:0]                      :
435
                          source_sel[C_CORE] ? address                                               :
436
                                               {CACHE_ADDR_WIDTH{1'd0}}                              ;
437
 
438
 
439
assign data_address     = consecutive_write  ? miss_address[CACHE_ADDR32_MSB:CACHE_ADDR32_LSB] :
440
                          write_hit          ? i_address   [CACHE_ADDR32_MSB:CACHE_ADDR32_LSB] :
441
                          source_sel[C_FILL] ? miss_address[CACHE_ADDR32_MSB:CACHE_ADDR32_LSB] :
442
                          source_sel[C_CORE] ? address                                         :
443
                                               {CACHE_ADDR_WIDTH{1'd0}}                        ;
444
 
445
 
446
assign tag_wdata        = source_sel[C_FILL] ? {1'd1, miss_address[31:TAG_ADDR32_LSB]} :
447
                                               {TAG_WIDTH{1'd0}}                       ;
448
 
449
 
450
    // Data comes in off the WB bus in wrap4 with the missed data word first
451
assign data_wdata       = write_hit && c_state == CS_IDLE ? write_hit_wdata :
452
                          consecutive_write               ? consecutive_write_wdata :
453
                                                            read_miss_wdata ;
454
 
455 35 csantifort
assign read_miss_wdata  = wb_rdata_burst;
456 16 csantifort
 
457
 
458
assign write_hit_wdata  = i_address[3:2] == 2'd0 ? {hit_rdata[127:32], write_data_word                   } :
459
                          i_address[3:2] == 2'd1 ? {hit_rdata[127:64], write_data_word, hit_rdata[31:0]  } :
460
                          i_address[3:2] == 2'd2 ? {hit_rdata[127:96], write_data_word, hit_rdata[63:0]  } :
461
                                                   {                   write_data_word, hit_rdata[95:0]  } ;
462
wire [31:0] con_read_data_word;
463
wire [31:0] con_write_data_word;
464
 
465
assign consecutive_write_wdata =
466
                          i_address[3:2] == 2'd0 ? {data_wdata_r[127:32], con_write_data_word                           } :
467
                          i_address[3:2] == 2'd1 ? {data_wdata_r[127:64], con_write_data_word, data_wdata_r[31:0]  } :
468
                          i_address[3:2] == 2'd2 ? {data_wdata_r[127:96], con_write_data_word, data_wdata_r[63:0]  } :
469
                                                   {                      con_write_data_word, data_wdata_r[95:0]  } ;
470
assign con_read_data_word =
471
                          i_address[3:2] == 2'd0 ? data_wdata_r[ 31:  0] :
472
                          i_address[3:2] == 2'd1 ? data_wdata_r[ 63: 32] :
473
                          i_address[3:2] == 2'd2 ? data_wdata_r[ 95: 64] :
474
                                                   data_wdata_r[127: 96] ;
475
 
476
 
477
assign con_write_data_word  = i_byte_enable == 4'b0001 ? { con_read_data_word[31: 8], i_write_data[ 7: 0]                          } :
478
                              i_byte_enable == 4'b0010 ? { con_read_data_word[31:16], i_write_data[15: 8], con_read_data_word[ 7:0]} :
479
                              i_byte_enable == 4'b0100 ? { con_read_data_word[31:24], i_write_data[23:16], con_read_data_word[15:0]} :
480
                              i_byte_enable == 4'b1000 ? {                            i_write_data[31:24], con_read_data_word[23:0]} :
481
                              i_byte_enable == 4'b0011 ? { con_read_data_word[31:16], i_write_data[15: 0]                          } :
482
                              i_byte_enable == 4'b1100 ? {                            i_write_data[31:16], con_read_data_word[15:0]} :
483
                                                                       i_write_data                                                  ;
484
 
485
 
486
 
487
 
488
// Use Byte Enables
489
assign write_data_word  = i_byte_enable == 4'b0001 ? { o_read_data[31: 8], i_write_data[ 7: 0]                   } :
490
                          i_byte_enable == 4'b0010 ? { o_read_data[31:16], i_write_data[15: 8], o_read_data[ 7:0]} :
491
                          i_byte_enable == 4'b0100 ? { o_read_data[31:24], i_write_data[23:16], o_read_data[15:0]} :
492
                          i_byte_enable == 4'b1000 ? {                     i_write_data[31:24], o_read_data[23:0]} :
493
                          i_byte_enable == 4'b0011 ? { o_read_data[31:16], i_write_data[15: 0]                   } :
494
                          i_byte_enable == 4'b1100 ? {                     i_write_data[31:16], o_read_data[15:0]} :
495
                                                     i_write_data                                                  ;
496
 
497
 
498
assign tag_wenable      = source_sel[C_INVA] ? 1'd1  :
499
                          source_sel[C_FILL] ? 1'd1  :
500
                          source_sel[C_INIT] ? 1'd1  :
501
                          source_sel[C_CORE] ? 1'd0  :
502
                                               1'd0  ;
503
 
504
 
505
assign request_pulse    = i_request && i_cache_enable;
506
 
507
assign exclusive_access = i_exclusive && i_cache_enable;
508
 
509
 
510
assign idle_hit         = |data_hit_way;
511
 
512
assign write_hit        = request_hold &&  i_write_enable && idle_hit;
513
 
514
assign write_miss       = request_hold &&  i_write_enable && !idle_hit && !consecutive_write;
515
 
516
assign read_miss        = request_hold && !idle_hit && !i_write_enable;
517
 
518
                          // Exclusive read idle_hit
519
assign ex_read_hit      = exclusive_access && !i_write_enable && idle_hit;
520
 
521
                          // Added to fix rare swap bug which occurs when the cache starts
522
                          // a fill just as the swap instruction starts to execute. The cache
523
                          // fails to check for a read idle_hit on the swap read cycle.
524
                          // This signal stalls the core in that case until after the
525
                          // fill has completed.
526
assign ex_read_cache_busy = exclusive_access && !i_write_enable && c_state != CS_IDLE;
527
 
528
                          // Need to stall for a write miss to wait for the current wb 
529
                          // read miss access to complete. Also for a write idle_hit, need 
530
                          // to stall for 1 cycle while the data cache is being written to
531 39 csantifort
assign write_state      = c_state == CS_IDLE || c_state == CS_WRITE_HIT ||
532 16 csantifort
                          c_state == CS_WRITE_HIT_WAIT_WB ||  c_state == CS_WRITE_MISS_WAIT_WB;
533
 
534 35 csantifort
assign write_stall      = (write_miss && !(i_wb_cached_ready && write_state)) || (write_hit && !i_wb_cached_ready);
535 16 csantifort
 
536
assign read_stall       = request_hold && !idle_hit && !rbuf_hit && !wb_hit && !i_write_enable;
537
 
538
assign cache_busy_stall = c_state == CS_FILL_COMPLETE || c_state == CS_TURN_AROUND || c_state == CS_INIT ||
539 35 csantifort
                          (fill_state && !rbuf_hit && !wb_hit) ||
540 39 csantifort
                          (c_state == CS_WRITE_HIT && !consecutive_write);
541 16 csantifort
 
542
 
543
// ======================================
544
// Instantiate RAMS
545
// ======================================
546
 
547
generate
548
    for ( i=0; i<WAYS;i=i+1 ) begin : rams
549
 
550
        // Tag RAMs 
551
        `ifdef XILINX_SPARTAN6_FPGA
552
        xs6_sram_256x21_line_en
553
        `endif
554
 
555
        `ifdef XILINX_VIRTEX6_FPGA
556
        xv6_sram_256x21_line_en
557
        `endif
558
 
559
        `ifndef XILINX_FPGA
560
        generic_sram_line_en
561
        `endif
562
 
563
            #(
564
            .DATA_WIDTH                 ( TAG_WIDTH             ),
565
            .INITIALIZE_TO_ZERO         ( 1                     ),
566
            .ADDRESS_WIDTH              ( CACHE_ADDR_WIDTH      ))
567
        u_tag (
568
            .i_clk                      ( i_clk                 ),
569
            .i_write_data               ( tag_wdata             ),
570
            .i_write_enable             ( tag_wenable_way[i]    ),
571
            .i_address                  ( tag_address           ),
572
 
573
            .o_read_data                ( tag_rdata_way[i]      )
574
            );
575
 
576
        // Data RAMs 
577
        `ifdef XILINX_SPARTAN6_FPGA
578
        xs6_sram_256x128_byte_en
579
        `endif
580
 
581
        `ifdef XILINX_VIRTEX6_FPGA
582
        xv6_sram_256x128_byte_en
583
        `endif
584
 
585
        `ifndef XILINX_FPGA
586
        generic_sram_byte_en
587
        `endif
588
 
589
            #(
590
            .DATA_WIDTH    ( CACHE_LINE_WIDTH) ,
591
            .ADDRESS_WIDTH ( CACHE_ADDR_WIDTH) )
592
        u_data (
593
            .i_clk                      ( i_clk                         ),
594
            .i_write_data               ( data_wdata                    ),
595
            .i_write_enable             ( data_wenable_way[i]           ),
596
            .i_address                  ( data_address                  ),
597
            .i_byte_enable              ( {CACHE_LINE_WIDTH/8{1'd1}}    ),
598
            .o_read_data                ( data_rdata_way[i]             )
599
            );
600
 
601
 
602
        // Per tag-ram write-enable
603
        assign tag_wenable_way[i]  = tag_wenable && ( select_way[i] || source_sel[C_INIT] );
604
 
605
        // Per data-ram write-enable
606
        assign data_wenable_way[i] = (source_sel[C_FILL] && select_way[i]) ||
607
                                     (write_hit && data_hit_way[i] && c_state == CS_IDLE) ||
608
                                     (consecutive_write && data_hit_way_r[i]);
609
        // Per data-ram idle_hit flag
610
        assign data_hit_way[i]     = tag_rdata_way[i][TAG_WIDTH-1] &&
611
                                     tag_rdata_way[i][TAG_ADDR_WIDTH-1:0] == i_address[31:TAG_ADDR32_LSB] &&
612
                                     c_state == CS_IDLE;
613
    end
614
endgenerate
615
 
616
 
617
// ======================================
618
// Register Valid Bits
619
// ======================================
620
generate
621
if ( WAYS == 2 ) begin : valid_bits_2ways
622
 
623
    always @ ( posedge i_clk )
624
        if ( c_state == CS_IDLE )
625
            valid_bits_r <= {tag_rdata_way[1][TAG_WIDTH-1],
626
                             tag_rdata_way[0][TAG_WIDTH-1]};
627
 
628
end
629
else if ( WAYS == 3 ) begin : valid_bits_3ways
630
 
631
    always @ ( posedge i_clk )
632
        if ( c_state == CS_IDLE )
633
            valid_bits_r <= {tag_rdata_way[2][TAG_WIDTH-1],
634
                             tag_rdata_way[1][TAG_WIDTH-1],
635
                             tag_rdata_way[0][TAG_WIDTH-1]};
636
 
637
end
638
else if ( WAYS == 4 ) begin : valid_bits_4ways
639
 
640
    always @ ( posedge i_clk )
641
        if ( c_state == CS_IDLE )
642
            valid_bits_r <= {tag_rdata_way[3][TAG_WIDTH-1],
643
                             tag_rdata_way[2][TAG_WIDTH-1],
644
                             tag_rdata_way[1][TAG_WIDTH-1],
645
                             tag_rdata_way[0][TAG_WIDTH-1]};
646
 
647
end
648
else begin : valid_bits_8ways
649
 
650
    always @ ( posedge i_clk )
651
        if ( c_state == CS_IDLE )
652
            valid_bits_r <= {tag_rdata_way[7][TAG_WIDTH-1],
653
                             tag_rdata_way[6][TAG_WIDTH-1],
654
                             tag_rdata_way[5][TAG_WIDTH-1],
655
                             tag_rdata_way[4][TAG_WIDTH-1],
656
                             tag_rdata_way[3][TAG_WIDTH-1],
657
                             tag_rdata_way[2][TAG_WIDTH-1],
658
                             tag_rdata_way[1][TAG_WIDTH-1],
659
                             tag_rdata_way[0][TAG_WIDTH-1]};
660
 
661
end
662
endgenerate
663
 
664
 
665
// ======================================
666
// Select read idle_hit data
667
// ======================================
668
 
669
generate
670
if ( WAYS == 2 ) begin : read_data_2ways
671
 
672
    assign hit_rdata    = data_hit_way[0] ? data_rdata_way[0] :
673
                          data_hit_way[1] ? data_rdata_way[1] :
674
                                     {CACHE_LINE_WIDTH{1'd1}} ;  // all 1's for debug
675
 
676
end
677
else if ( WAYS == 3 ) begin : read_data_3ways
678
 
679
    assign hit_rdata    = data_hit_way[0] ? data_rdata_way[0] :
680
                          data_hit_way[1] ? data_rdata_way[1] :
681
                          data_hit_way[2] ? data_rdata_way[2] :
682
                                     {CACHE_LINE_WIDTH{1'd1}} ;  // all 1's for debug
683
 
684
end
685
else if ( WAYS == 4 ) begin : read_data_4ways
686
 
687
    assign hit_rdata    = data_hit_way[0] ? data_rdata_way[0] :
688
                          data_hit_way[1] ? data_rdata_way[1] :
689
                          data_hit_way[2] ? data_rdata_way[2] :
690
                          data_hit_way[3] ? data_rdata_way[3] :
691
                                     {CACHE_LINE_WIDTH{1'd1}} ;  // all 1's for debug
692
 
693
end
694
else begin : read_data_8ways
695
 
696
    assign hit_rdata    = data_hit_way[0] ? data_rdata_way[0] :
697
                          data_hit_way[1] ? data_rdata_way[1] :
698
                          data_hit_way[2] ? data_rdata_way[2] :
699
                          data_hit_way[3] ? data_rdata_way[3] :
700
                          data_hit_way[4] ? data_rdata_way[4] :
701
                          data_hit_way[5] ? data_rdata_way[5] :
702
                          data_hit_way[6] ? data_rdata_way[6] :
703
                          data_hit_way[7] ? data_rdata_way[7] :
704
                                     {CACHE_LINE_WIDTH{1'd1}} ;  // all 1's for debug
705
 
706
end
707
endgenerate
708
 
709
 
710
// ======================================
711
// Function to select the way to use
712
// for fills
713
// ======================================
714
generate
715
if ( WAYS == 2 ) begin : pick_way_2ways
716
 
717
    assign next_way = pick_way ( valid_bits_r, random_num );
718
 
719
    function [WAYS-1:0] pick_way;
720
    input [WAYS-1:0] valid_bits;
721
    input [3:0]      random_num;
722
    begin
723
        if (      valid_bits[0] == 1'd0 )
724
            // way 0 not occupied so use it
725
            pick_way     = 2'b01;
726
        else if ( valid_bits[1] == 1'd0 )
727
            // way 1 not occupied so use it
728
            pick_way     = 2'b10;
729
        else
730
            begin
731
            // All ways occupied so pick one randomly
732
            case (random_num[3:1])
733
                3'd0, 3'd3,
734
                3'd5, 3'd6: pick_way = 2'b10;
735
                default:    pick_way = 2'b01;
736
            endcase
737
            end
738
    end
739
    endfunction
740
 
741
end
742
else if ( WAYS == 3 ) begin : pick_way_3ways
743
 
744
    assign next_way = pick_way ( valid_bits_r, random_num );
745
 
746
    function [WAYS-1:0] pick_way;
747
    input [WAYS-1:0] valid_bits;
748
    input [3:0]      random_num;
749
    begin
750
        if (      valid_bits[0] == 1'd0 )
751
            // way 0 not occupied so use it
752
            pick_way     = 3'b001;
753
        else if ( valid_bits[1] == 1'd0 )
754
            // way 1 not occupied so use it
755
            pick_way     = 3'b010;
756
        else if ( valid_bits[2] == 1'd0 )
757
            // way 2 not occupied so use it
758
            pick_way     = 3'b100;
759
        else
760
            begin
761
            // All ways occupied so pick one randomly
762
            case (random_num[3:1])
763
                3'd0, 3'd1, 3'd2: pick_way = 3'b010;
764
                3'd2, 3'd3, 3'd4: pick_way = 3'b100;
765
                default:          pick_way = 3'b001;
766
            endcase
767
            end
768
    end
769
    endfunction
770
 
771
end
772
else if ( WAYS == 4 ) begin : pick_way_4ways
773
 
774
    assign next_way = pick_way ( valid_bits_r, random_num );
775
 
776
    function [WAYS-1:0] pick_way;
777
    input [WAYS-1:0] valid_bits;
778
    input [3:0]      random_num;
779
    begin
780
        if (      valid_bits[0] == 1'd0 )
781
            // way 0 not occupied so use it
782
            pick_way     = 4'b0001;
783
        else if ( valid_bits[1] == 1'd0 )
784
            // way 1 not occupied so use it
785
            pick_way     = 4'b0010;
786
        else if ( valid_bits[2] == 1'd0 )
787
            // way 2 not occupied so use it
788
            pick_way     = 4'b0100;
789
        else if ( valid_bits[3] == 1'd0 )
790
            // way 3 not occupied so use it
791
            pick_way     = 4'b1000;
792
        else
793
            begin
794
            // All ways occupied so pick one randomly
795
            case (random_num[3:1])
796
                3'd0, 3'd1: pick_way = 4'b0100;
797
                3'd2, 3'd3: pick_way = 4'b1000;
798
                3'd4, 3'd5: pick_way = 4'b0001;
799
                default:    pick_way = 4'b0010;
800
            endcase
801
            end
802
    end
803
    endfunction
804
 
805
end
806
else begin : pick_way_8ways
807
 
808
    assign next_way = pick_way ( valid_bits_r, random_num );
809
 
810
    function [WAYS-1:0] pick_way;
811
    input [WAYS-1:0] valid_bits;
812
    input [3:0]      random_num;
813
    begin
814
        if (      valid_bits[0] == 1'd0 )
815
            // way 0 not occupied so use it
816
            pick_way     = 8'b00000001;
817
        else if ( valid_bits[1] == 1'd0 )
818
            // way 1 not occupied so use it
819
            pick_way     = 8'b00000010;
820
        else if ( valid_bits[2] == 1'd0 )
821
            // way 2 not occupied so use it
822
            pick_way     = 8'b00000100;
823
        else if ( valid_bits[3] == 1'd0 )
824
            // way 3 not occupied so use it
825
            pick_way     = 8'b00001000;
826
        else if ( valid_bits[4] == 1'd0 )
827
            // way 3 not occupied so use it
828
            pick_way     = 8'b00010000;
829
        else if ( valid_bits[5] == 1'd0 )
830
            // way 3 not occupied so use it
831
            pick_way     = 8'b00100000;
832
        else if ( valid_bits[6] == 1'd0 )
833
            // way 3 not occupied so use it
834
            pick_way     = 8'b01000000;
835
        else if ( valid_bits[7] == 1'd0 )
836
            // way 3 not occupied so use it
837
            pick_way     = 8'b10000000;
838
        else
839
            begin
840
            // All ways occupied so pick one randomly
841
            case (random_num[3:1])
842
                3'd0:       pick_way = 8'b00010000;
843
                3'd1:       pick_way = 8'b00100000;
844
                3'd2:       pick_way = 8'b01000000;
845
                3'd3:       pick_way = 8'b10000000;
846
                3'd4:       pick_way = 8'b00000001;
847
                3'd5:       pick_way = 8'b00000010;
848
                3'd6:       pick_way = 8'b00000100;
849
                default:    pick_way = 8'b00001000;
850
            endcase
851
            end
852
    end
853
    endfunction
854
 
855
end
856
endgenerate
857
 
858
 
859
// ========================================================
860
// Debug WB bus - not synthesizable
861
// ========================================================
862
//synopsys translate_off
863
wire    [(6*8)-1:0]     xSOURCE_SEL;
864
wire    [(22*8)-1:0]    xC_STATE;
865
 
866
assign xSOURCE_SEL = source_sel[C_CORE]               ? "C_CORE"                :
867
                     source_sel[C_INIT]               ? "C_INIT"                :
868
                     source_sel[C_FILL]               ? "C_FILL"                :
869
                     source_sel[C_INVA]               ? "C_INVA"                :
870
                                                        "UNKNON"                ;
871
 
872 39 csantifort
assign xC_STATE    = c_state == CS_INIT               ? "INIT"               :
873
                     c_state == CS_IDLE               ? "IDLE"               :
874
                     c_state == CS_FILL               ? "FILL"               :
875
                     c_state == CS_FILL_COMPLETE      ? "FILL_COMPLETE"      :
876
                     c_state == CS_EX_DELETE          ? "EX_DELETE"          :
877
                     c_state == CS_TURN_AROUND        ? "TURN_AROUND"        :
878
                     c_state == CS_WRITE_HIT          ? "WRITE_HIT"          :
879
                     c_state == CS_WRITE_HIT_WAIT_WB  ? "WRITE_HIT_WAIT_WB"  :
880
                     c_state == CS_WRITE_MISS_WAIT_WB ? "WRITE_MISS_WAIT_WB" :
881 16 csantifort
                                                        "UNKNOWN"               ;
882
 
883
 
884
generate
885
if ( WAYS == 2 ) begin : check_hit_2ways
886
 
887
    always @( posedge i_clk )
888
        if ( (data_hit_way[0] + data_hit_way[1] ) > 4'd1 )
889
            begin
890
            `TB_ERROR_MESSAGE
891
            $display("Hit in more than one cache ways!");
892
            end
893
 
894
end
895
else if ( WAYS == 3 ) begin : check_hit_3ways
896
 
897
    always @( posedge i_clk )
898
        if ( (data_hit_way[0] + data_hit_way[1] + data_hit_way[2] ) > 4'd1 )
899
            begin
900
            `TB_ERROR_MESSAGE
901
            $display("Hit in more than one cache ways!");
902
            end
903
 
904
end
905
else if ( WAYS == 4 ) begin : check_hit_4ways
906
 
907
    always @( posedge i_clk )
908
        if ( (data_hit_way[0] + data_hit_way[1] +
909
              data_hit_way[2] + data_hit_way[3] ) > 4'd1 )
910
            begin
911
            `TB_ERROR_MESSAGE
912
            $display("Hit in more than one cache ways!");
913
            end
914
 
915
end
916
else if ( WAYS == 8 )  begin : check_hit_8ways
917
 
918
    always @( posedge i_clk )
919
        if ( (data_hit_way[0] + data_hit_way[1] +
920
              data_hit_way[2] + data_hit_way[3] +
921
              data_hit_way[4] + data_hit_way[5] +
922
              data_hit_way[6] + data_hit_way[7] ) > 4'd1 )
923
            begin
924
            `TB_ERROR_MESSAGE
925
            $display("Hit in more than one cache ways!");
926
            end
927
 
928
end
929
else begin : check_hit_nways
930
 
931
    initial
932
        begin
933
        `TB_ERROR_MESSAGE
934
        $display("Unsupported number of ways %0d", WAYS);
935
        $display("Set A25_DCACHE_WAYS in a25_config_defines.v to either 2,3,4 or 8");
936
        end
937
 
938
end
939
endgenerate
940
 
941
 
942
//synopsys translate_on
943
 
944
endmodule
945
 

powered by: WebSVN 2.1.0

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