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

Subversion Repositories amber

[/] [amber/] [trunk/] [hw/] [vlog/] [amber25/] [a25_icache.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
//  L1 Instruction Cache for Amber 25 Core                      //
4
//                                                              //
5
//  This file is part of the Amber project                      //
6
//  http://www.opencores.org/project,amber                      //
7
//                                                              //
8
//  Description                                                 //
9 17 csantifort
//  Synthesizable L1 Instruction Cache.                         //
10
//  Cache is 2,3,4 or 8 way, 256 line and 16 bytes per line.    //
11
//  a total of 16KB. The cache is read only. Writes from        //
12
//  the core to through the data cache.                         //
13 16 csantifort
//                                                              //
14
//  Author(s):                                                  //
15
//      - Conor Santifort, csantifort.amber@gmail.com           //
16
//                                                              //
17
//////////////////////////////////////////////////////////////////
18
//                                                              //
19
// Copyright (C) 2011 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
`include "a25_config_defines.v"
45
 
46
module a25_icache
47
#(
48
 
49
// ---------------------------------------------------------
50
// Cache Configuration
51
 
52
// Limited to Linux 4k page sizes -> 256 lines
53
parameter CACHE_LINES          = 256,
54
 
55
// This cannot be changed without some major surgeory on
56
// this module                                       
57
parameter CACHE_WORDS_PER_LINE = 4,
58
 
59
// Changing this parameter is the recommended
60
// way to change the overall cache size; 2, 4 and 8 ways are supported.
61
//   2 ways -> 8KB  cache
62
//   4 ways -> 16KB cache
63
//   8 ways -> 32KB cache
64
parameter WAYS              = `A25_ICACHE_WAYS ,
65
 
66
// derived configuration parameters
67
parameter CACHE_ADDR_WIDTH  = log2 ( CACHE_LINES ),                        // = 8
68
parameter WORD_SEL_WIDTH    = log2 ( CACHE_WORDS_PER_LINE ),               // = 2
69
parameter TAG_ADDR_WIDTH    = 32 - CACHE_ADDR_WIDTH - WORD_SEL_WIDTH - 2,  // = 20
70
parameter TAG_WIDTH         = TAG_ADDR_WIDTH + 1,                          // = 21, including Valid flag
71
parameter CACHE_LINE_WIDTH  = CACHE_WORDS_PER_LINE * 32,                   // = 128
72
parameter TAG_ADDR32_LSB    = CACHE_ADDR_WIDTH + WORD_SEL_WIDTH + 2,       // = 12
73
parameter CACHE_ADDR32_MSB  = CACHE_ADDR_WIDTH + WORD_SEL_WIDTH + 2 - 1,   // = 11
74
parameter CACHE_ADDR32_LSB  =                    WORD_SEL_WIDTH + 2    ,   // = 4
75
parameter WORD_SEL_MSB      = WORD_SEL_WIDTH + 2 - 1,                      // = 3
76
parameter WORD_SEL_LSB      =                  2                           // = 2
77
// ---------------------------------------------------------
78
)
79
 
80
 
81
(
82
input                               i_clk,
83
input                               i_core_stall,
84
output                              o_stall,
85
 
86
// Read / Write requests from core
87
input                               i_select,
88
input      [31:0]                   i_address,          // registered address from execute
89
input      [31:0]                   i_address_nxt,      // un-registered version of address from execute stage
90
input                               i_cache_enable,     // from co-processor 15 configuration register
91
input                               i_cache_flush,      // from co-processor 15 register
92
 
93 35 csantifort
output     [127:0]                  o_read_data,
94 16 csantifort
 
95
// WB Read Request                                                          
96
output                              o_wb_req,          // Read Request
97 35 csantifort
input      [127:0]                  i_wb_read_data,
98 16 csantifort
input                               i_wb_ready
99
);
100
 
101
`include "a25_localparams.v"
102
`include "a25_functions.v"
103
 
104
// One-hot encoded
105
localparam       C_INIT   = 0,
106
                 C_CORE   = 1,
107
                 C_FILL   = 2,
108
                 C_INVA   = 3,
109
                 C_STATES = 4;
110
 
111
localparam [3:0] CS_INIT            = 4'd0,
112
                 CS_IDLE            = 4'd1,
113
                 CS_FILL0           = 4'd2,
114
                 CS_FILL1           = 4'd3,
115
                 CS_FILL2           = 4'd4,
116
                 CS_FILL3           = 4'd5,
117
                 CS_FILL4           = 4'd6,
118
                 CS_FILL_COMPLETE   = 4'd7,
119
                 CS_TURN_AROUND     = 4'd8,
120
                 CS_WRITE_HIT1      = 4'd9,
121
                 CS_EX_DELETE       = 4'd10;
122
 
123
 
124
reg  [3:0]                  c_state    = CS_IDLE;
125
reg  [C_STATES-1:0]         source_sel = 1'd1 << C_CORE;
126
reg  [CACHE_ADDR_WIDTH:0]   init_count = 'd0;
127
 
128
wire [TAG_WIDTH-1:0]        tag_rdata_way [WAYS-1:0];
129
wire [CACHE_LINE_WIDTH-1:0] data_rdata_way[WAYS-1:0];
130
wire [WAYS-1:0]             data_wenable_way;
131
wire [WAYS-1:0]             data_hit_way;
132
wire [WAYS-1:0]             tag_wenable_way;
133
reg  [WAYS-1:0]             select_way = 'd0;
134
wire [WAYS-1:0]             next_way;
135
reg  [WAYS-1:0]             valid_bits_r = 'd0;
136
 
137
reg  [3:0]                  random_num = 4'hf;
138
 
139
wire [CACHE_ADDR_WIDTH-1:0] tag_address;
140
wire [TAG_WIDTH-1:0]        tag_wdata;
141
wire                        tag_wenable;
142
 
143
wire [CACHE_ADDR_WIDTH-1:0] data_address;
144
wire [31:0]                 write_data_word;
145
 
146
wire                        idle_hit;
147
wire                        read_miss;
148
wire                        read_miss_fill;
149
wire                        invalid_read;
150
wire                        fill_state;
151
 
152
reg  [31:0]                 miss_address = 'd0;
153
wire [CACHE_LINE_WIDTH-1:0] hit_rdata;
154
 
155
wire                        cache_busy_stall;
156
wire                        read_stall;
157
 
158
wire                        enable;
159
wire [CACHE_ADDR_WIDTH-1:0] address;
160
wire [31:0]                 address_c;
161
reg  [31:0]                 address_r = 'd0;
162
 
163
reg  [31:0]                 wb_address = 'd0;
164
wire                        wb_hit;
165 35 csantifort
wire                        read_buf_hit;
166
reg  [127:0]                read_buf_data_r;
167
reg  [31:0]                 read_buf_addr_r;
168
reg                         read_buf_valid_r;
169 16 csantifort
genvar                      i;
170
 
171
// ======================================
172
// Address to use for cache access
173
// ======================================
174
// If currently stalled then the address for the next
175
// cycle will be the same as it is in the current cycle
176
//
177 35 csantifort
assign address_c = i_core_stall ? i_address    :
178
                                  i_address_nxt;
179 16 csantifort
 
180
assign address   = address_c[CACHE_ADDR32_MSB:CACHE_ADDR32_LSB];
181
 
182 35 csantifort
 
183 16 csantifort
// ======================================
184
// Outputs
185
// ======================================
186 35 csantifort
assign o_read_data      = wb_hit       ? i_wb_read_data  :
187
                          read_buf_hit ? read_buf_data_r :
188
                                         hit_rdata ;
189 16 csantifort
 
190 35 csantifort
 
191 16 csantifort
// Don't allow the cache to stall the wb i/f for an exclusive access
192
// The cache needs a couple of cycles to flush a potential copy of the exclusive
193
// address, but the wb can do the access in parallel. So there is no
194
// stall in the state CS_EX_DELETE, even though the cache is out of action. 
195
// This works fine as long as the wb is stalling the core
196
assign o_stall          = read_stall  || cache_busy_stall;
197
 
198
assign o_wb_req         = read_miss && c_state == CS_IDLE;
199
 
200 35 csantifort
 
201
// ======================================
202
// Read Buffer
203
// ======================================
204
always@(posedge i_clk)
205
    if ( i_cache_flush )
206
        read_buf_valid_r <= 1'd0;
207
    else if (i_wb_ready && c_state == CS_FILL3)
208
        begin
209
        read_buf_data_r  <= i_wb_read_data;
210
        read_buf_addr_r  <= miss_address;
211
        read_buf_valid_r <= 1'd1;
212
        end
213
    else if (o_wb_req)
214
        read_buf_valid_r <= 1'd0;
215
 
216
 
217
assign read_buf_hit     = read_buf_valid_r && i_address[31:4] == read_buf_addr_r[31:4];
218 16 csantifort
 
219
// ======================================
220
// Cache State Machine
221
// ======================================
222
 
223
// Little State Machine to Flush Tag RAMS
224
always @ ( posedge i_clk )
225
    if ( i_cache_flush )
226
        begin
227
        c_state     <= CS_INIT;
228
        source_sel  <= 1'd1 << C_INIT;
229
        init_count  <= 'd0;
230
        `ifdef A25_CACHE_DEBUG
231
        `TB_DEBUG_MESSAGE
232
        $display("Cache Flush");
233
        `endif
234
        end
235
    else
236
        case ( c_state )
237
            CS_INIT :
238
                if ( init_count < CACHE_LINES [CACHE_ADDR_WIDTH:0] )
239
                    begin
240
                    init_count  <= init_count + 1'd1;
241
                    source_sel  <= 1'd1 << C_INIT;
242
                    end
243
                else
244
                    begin
245
                    source_sel  <= 1'd1 << C_CORE;
246
                    c_state     <= CS_TURN_AROUND;
247
                    end
248
 
249
             CS_IDLE :
250
                begin
251
                source_sel  <= 1'd1 << C_CORE;
252
 
253
                if ( read_miss )
254 35 csantifort
                    c_state <= CS_FILL3;
255 16 csantifort
               end
256
 
257
 
258
             CS_FILL3 :
259
                begin
260 35 csantifort
                // Pick a way to write the cache update into
261
                // Either pick one of the invalid caches, or if all are valid, then pick
262
                // one randomly
263 16 csantifort
                select_way  <= next_way;
264
                random_num  <= {random_num[2], random_num[1], random_num[0],
265
                                 random_num[3]^random_num[2]};
266
 
267
                // third read of burst of 4
268
                // wb read request asserted, wait for ack
269
                if ( i_wb_ready )
270
                    begin
271
                    c_state     <= CS_FILL_COMPLETE;
272
                    end
273
                end
274
 
275
 
276
             // Write the read fetch data in this cycle
277
             CS_FILL_COMPLETE :
278
                begin
279
                // Back to normal cache operations, but
280
                // use physical address for first read as
281
                // address moved before the stall was asserted for the read_miss
282
                // However don't use it if its a non-cached address!
283
                source_sel  <= 1'd1 << C_CORE;
284
                c_state     <= CS_TURN_AROUND;
285
                end
286
 
287
 
288
             // Ignore the tag read data in this cycle   
289
             // Wait 1 cycle to pre-read the cache and return to normal operation                 
290
             CS_TURN_AROUND :
291
                begin
292
                c_state     <= CS_IDLE;
293
                end
294
 
295
        endcase
296
 
297
 
298
// ======================================
299
// Miss Address
300
// ======================================
301
always @ ( posedge i_clk )
302
    if ( c_state == CS_IDLE )
303
        miss_address <= i_address;
304
 
305
 
306
always @ ( posedge i_clk )
307
    address_r <= address_c;
308
 
309
assign invalid_read = address_r != i_address;
310
 
311
 
312
always @(posedge i_clk)
313
    if ( o_wb_req )
314
        wb_address <= i_address;
315
    else if ( i_wb_ready && fill_state )
316
        wb_address <= {wb_address[31:4], wb_address[3:2] + 1'd1, 2'd0};
317
 
318 35 csantifort
assign fill_state       = c_state == CS_FILL3;
319 16 csantifort
assign wb_hit           = i_address == wb_address && i_wb_ready && fill_state;
320
 
321
assign tag_address      = read_miss_fill     ? miss_address      [CACHE_ADDR32_MSB:CACHE_ADDR32_LSB] :
322
                          source_sel[C_INIT] ? init_count[CACHE_ADDR_WIDTH-1:0]                      :
323
                                               address                                               ;
324
 
325
 
326
assign data_address     = read_miss_fill     ? miss_address[CACHE_ADDR32_MSB:CACHE_ADDR32_LSB] :
327
                                               address                                         ;
328
 
329
 
330
assign tag_wdata        = read_miss_fill     ? {1'd1, miss_address[31:TAG_ADDR32_LSB]} :
331
                                               {TAG_WIDTH{1'd0}}                       ;
332
 
333
 
334
assign read_miss_fill   = c_state == CS_FILL3 && i_wb_ready;
335
 
336
 
337
 
338
assign tag_wenable      = read_miss_fill     ? 1'd1  :
339
                          source_sel[C_INVA] ? 1'd1  :
340
                          source_sel[C_FILL] ? 1'd1  :
341
                          source_sel[C_INIT] ? 1'd1  :
342
                          source_sel[C_CORE] ? 1'd0  :
343
                                               1'd0  ;
344
 
345
 
346
assign enable           = i_select && i_cache_enable;
347
 
348
assign idle_hit         = |data_hit_way;
349
 
350
assign read_miss        = enable && !idle_hit && !invalid_read;
351
 
352 35 csantifort
assign read_stall       = enable && !idle_hit && !wb_hit && !read_buf_hit;
353 16 csantifort
 
354 35 csantifort
assign cache_busy_stall = (c_state == CS_TURN_AROUND  && enable && !read_buf_hit) || c_state == CS_INIT;
355 16 csantifort
 
356
 
357
// ======================================
358
// Instantiate RAMS
359
// ======================================
360
 
361
generate
362
    for ( i=0; i<WAYS;i=i+1 ) begin : rams
363
 
364
        // Tag RAMs 
365
        `ifdef XILINX_SPARTAN6_FPGA
366
        xs6_sram_256x21_line_en
367
        `endif
368
 
369
        `ifdef XILINX_VIRTEX6_FPGA
370
        xv6_sram_256x21_line_en
371
        `endif
372
 
373
        `ifndef XILINX_FPGA
374
        generic_sram_line_en
375
        `endif
376
 
377
            #(
378
            .DATA_WIDTH                 ( TAG_WIDTH             ),
379
            .INITIALIZE_TO_ZERO         ( 1                     ),
380
            .ADDRESS_WIDTH              ( CACHE_ADDR_WIDTH      ))
381
        u_tag (
382
            .i_clk                      ( i_clk                 ),
383
            .i_write_data               ( tag_wdata             ),
384
            .i_write_enable             ( tag_wenable_way[i]    ),
385
            .i_address                  ( tag_address           ),
386
 
387
            .o_read_data                ( tag_rdata_way[i]      )
388
            );
389
 
390
        // Data RAMs 
391
        `ifdef XILINX_SPARTAN6_FPGA
392
        xs6_sram_256x128_byte_en
393
        `endif
394
 
395
        `ifdef XILINX_VIRTEX6_FPGA
396
        xv6_sram_256x128_byte_en
397
        `endif
398
 
399
        `ifndef XILINX_FPGA
400
        generic_sram_byte_en
401
        `endif
402
 
403
            #(
404
            .DATA_WIDTH    ( CACHE_LINE_WIDTH) ,
405
            .ADDRESS_WIDTH ( CACHE_ADDR_WIDTH) )
406
        u_data (
407
            .i_clk                      ( i_clk                         ),
408 35 csantifort
            .i_write_data               ( i_wb_read_data                ),
409 16 csantifort
            .i_write_enable             ( data_wenable_way[i]           ),
410
            .i_address                  ( data_address                  ),
411
            .i_byte_enable              ( {CACHE_LINE_WIDTH/8{1'd1}}    ),
412
            .o_read_data                ( data_rdata_way[i]             )
413
            );
414
 
415
 
416
        // Per tag-ram write-enable
417
        assign tag_wenable_way[i]  = tag_wenable && ( select_way[i] || source_sel[C_INIT] );
418
 
419
        // Per data-ram write-enable
420
        assign data_wenable_way[i] = ( source_sel[C_FILL] || read_miss_fill ) && select_way[i];
421
 
422
        // Per data-ram idle_hit flag
423
        assign data_hit_way[i]     = tag_rdata_way[i][TAG_WIDTH-1] &&
424
                                     tag_rdata_way[i][TAG_ADDR_WIDTH-1:0] == i_address[31:TAG_ADDR32_LSB] &&
425
                                     c_state == CS_IDLE;
426
    end
427
endgenerate
428
 
429
 
430
// ======================================
431
// Register Valid Bits
432
// ======================================
433
generate
434
if ( WAYS == 2 ) begin : valid_bits_2ways
435
 
436
    always @ ( posedge i_clk )
437
        if ( c_state == CS_IDLE )
438
            valid_bits_r <= {tag_rdata_way[1][TAG_WIDTH-1],
439
                             tag_rdata_way[0][TAG_WIDTH-1]};
440
 
441
end
442
else if ( WAYS == 3 ) begin : valid_bits_3ways
443
 
444
    always @ ( posedge i_clk )
445
        if ( c_state == CS_IDLE )
446
            valid_bits_r <= {tag_rdata_way[2][TAG_WIDTH-1],
447
                             tag_rdata_way[1][TAG_WIDTH-1],
448
                             tag_rdata_way[0][TAG_WIDTH-1]};
449
 
450
end
451
else if ( WAYS == 4 ) begin : valid_bits_4ways
452
 
453
    always @ ( posedge i_clk )
454
        if ( c_state == CS_IDLE )
455
            valid_bits_r <= {tag_rdata_way[3][TAG_WIDTH-1],
456
                             tag_rdata_way[2][TAG_WIDTH-1],
457
                             tag_rdata_way[1][TAG_WIDTH-1],
458
                             tag_rdata_way[0][TAG_WIDTH-1]};
459
 
460
end
461
else begin : valid_bits_8ways
462
 
463
    always @ ( posedge i_clk )
464
        if ( c_state == CS_IDLE )
465
            valid_bits_r <= {tag_rdata_way[7][TAG_WIDTH-1],
466
                             tag_rdata_way[6][TAG_WIDTH-1],
467
                             tag_rdata_way[5][TAG_WIDTH-1],
468
                             tag_rdata_way[4][TAG_WIDTH-1],
469
                             tag_rdata_way[3][TAG_WIDTH-1],
470
                             tag_rdata_way[2][TAG_WIDTH-1],
471
                             tag_rdata_way[1][TAG_WIDTH-1],
472
                             tag_rdata_way[0][TAG_WIDTH-1]};
473
 
474
end
475
endgenerate
476
 
477
 
478
// ======================================
479
// Select read hit data
480
// ======================================
481
generate
482
if ( WAYS == 2 ) begin : read_data_2ways
483
 
484
    assign hit_rdata    = data_hit_way[0] ? data_rdata_way[0] :
485
                          data_hit_way[1] ? data_rdata_way[1] :
486
                                     {CACHE_LINE_WIDTH{1'd1}} ;  // all 1's for debug
487
 
488
end
489
else if ( WAYS == 3 ) begin : read_data_3ways
490
 
491
    assign hit_rdata    = data_hit_way[0] ? data_rdata_way[0] :
492
                          data_hit_way[1] ? data_rdata_way[1] :
493
                          data_hit_way[2] ? data_rdata_way[2] :
494
                                     {CACHE_LINE_WIDTH{1'd1}} ;  // all 1's for debug
495
 
496
end
497
else if ( WAYS == 4 ) begin : read_data_4ways
498
 
499
    assign hit_rdata    = data_hit_way[0] ? data_rdata_way[0] :
500
                          data_hit_way[1] ? data_rdata_way[1] :
501
                          data_hit_way[2] ? data_rdata_way[2] :
502
                          data_hit_way[3] ? data_rdata_way[3] :
503
                                     {CACHE_LINE_WIDTH{1'd1}} ;  // all 1's for debug
504
 
505
end
506
else begin : read_data_8ways
507
 
508
    assign hit_rdata    = data_hit_way[0] ? data_rdata_way[0] :
509
                          data_hit_way[1] ? data_rdata_way[1] :
510
                          data_hit_way[2] ? data_rdata_way[2] :
511
                          data_hit_way[3] ? data_rdata_way[3] :
512
                          data_hit_way[4] ? data_rdata_way[4] :
513
                          data_hit_way[5] ? data_rdata_way[5] :
514
                          data_hit_way[6] ? data_rdata_way[6] :
515
                          data_hit_way[7] ? data_rdata_way[7] :
516
                                     {CACHE_LINE_WIDTH{1'd1}} ;  // all 1's for debug
517
 
518
end
519
endgenerate
520
 
521
 
522
// ======================================
523
// Function to select the way to use
524
// for fills
525
// ======================================
526
generate
527
if ( WAYS == 2 ) begin : pick_way_2ways
528
 
529
    assign next_way = pick_way ( valid_bits_r, random_num );
530
 
531
    function [WAYS-1:0] pick_way;
532
    input [WAYS-1:0] valid_bits;
533
    input [3:0]      random_num;
534
    begin
535
        if (      valid_bits[0] == 1'd0 )
536
            // way 0 not occupied so use it
537
            pick_way     = 2'b01;
538
        else if ( valid_bits[1] == 1'd0 )
539
            // way 1 not occupied so use it
540
            pick_way     = 2'b10;
541
        else
542
            begin
543
            // All ways occupied so pick one randomly
544
            case (random_num[3:1])
545
                3'd0, 3'd3,
546
                3'd5, 3'd6: pick_way = 2'b10;
547
                default:    pick_way = 2'b01;
548
            endcase
549
            end
550
    end
551
    endfunction
552
 
553
end
554
else if ( WAYS == 3 ) begin : pick_way_3ways
555
 
556
    assign next_way = pick_way ( valid_bits_r, random_num );
557
 
558
    function [WAYS-1:0] pick_way;
559
    input [WAYS-1:0] valid_bits;
560
    input [3:0]      random_num;
561
    begin
562
        if (      valid_bits[0] == 1'd0 )
563
            // way 0 not occupied so use it
564
            pick_way     = 3'b001;
565
        else if ( valid_bits[1] == 1'd0 )
566
            // way 1 not occupied so use it
567
            pick_way     = 3'b010;
568
        else if ( valid_bits[2] == 1'd0 )
569
            // way 2 not occupied so use it
570
            pick_way     = 3'b100;
571
        else
572
            begin
573
            // All ways occupied so pick one randomly
574
            case (random_num[3:1])
575
                3'd0, 3'd1, 3'd2: pick_way = 3'b010;
576
                3'd2, 3'd3, 3'd4: pick_way = 3'b100;
577
                default:          pick_way = 3'b001;
578
            endcase
579
            end
580
    end
581
    endfunction
582
 
583
end
584
else if ( WAYS == 4 ) begin : pick_way_4ways
585
 
586
    assign next_way = pick_way ( valid_bits_r, random_num );
587
 
588
    function [WAYS-1:0] pick_way;
589
    input [WAYS-1:0] valid_bits;
590
    input [3:0]      random_num;
591
    begin
592
        if (      valid_bits[0] == 1'd0 )
593
            // way 0 not occupied so use it
594
            pick_way     = 4'b0001;
595
        else if ( valid_bits[1] == 1'd0 )
596
            // way 1 not occupied so use it
597
            pick_way     = 4'b0010;
598
        else if ( valid_bits[2] == 1'd0 )
599
            // way 2 not occupied so use it
600
            pick_way     = 4'b0100;
601
        else if ( valid_bits[3] == 1'd0 )
602
            // way 3 not occupied so use it
603
            pick_way     = 4'b1000;
604
        else
605
            begin
606
            // All ways occupied so pick one randomly
607
            case (random_num[3:1])
608
                3'd0, 3'd1: pick_way = 4'b0100;
609
                3'd2, 3'd3: pick_way = 4'b1000;
610
                3'd4, 3'd5: pick_way = 4'b0001;
611
                default:    pick_way = 4'b0010;
612
            endcase
613
            end
614
    end
615
    endfunction
616
 
617
end
618
else begin : pick_way_8ways
619
 
620
    assign next_way = pick_way ( valid_bits_r, random_num );
621
 
622
    function [WAYS-1:0] pick_way;
623
    input [WAYS-1:0] valid_bits;
624
    input [3:0]      random_num;
625
    begin
626
        if (      valid_bits[0] == 1'd0 )
627
            // way 0 not occupied so use it
628
            pick_way     = 8'b00000001;
629
        else if ( valid_bits[1] == 1'd0 )
630
            // way 1 not occupied so use it
631
            pick_way     = 8'b00000010;
632
        else if ( valid_bits[2] == 1'd0 )
633
            // way 2 not occupied so use it
634
            pick_way     = 8'b00000100;
635
        else if ( valid_bits[3] == 1'd0 )
636
            // way 3 not occupied so use it
637
            pick_way     = 8'b00001000;
638
        else if ( valid_bits[4] == 1'd0 )
639
            // way 3 not occupied so use it
640
            pick_way     = 8'b00010000;
641
        else if ( valid_bits[5] == 1'd0 )
642
            // way 3 not occupied so use it
643
            pick_way     = 8'b00100000;
644
        else if ( valid_bits[6] == 1'd0 )
645
            // way 3 not occupied so use it
646
            pick_way     = 8'b01000000;
647
        else if ( valid_bits[7] == 1'd0 )
648
            // way 3 not occupied so use it
649
            pick_way     = 8'b10000000;
650
        else
651
            begin
652
            // All ways occupied so pick one randomly
653
            case (random_num[3:1])
654
                3'd0:       pick_way = 8'b00010000;
655
                3'd1:       pick_way = 8'b00100000;
656
                3'd2:       pick_way = 8'b01000000;
657
                3'd3:       pick_way = 8'b10000000;
658
                3'd4:       pick_way = 8'b00000001;
659
                3'd5:       pick_way = 8'b00000010;
660
                3'd6:       pick_way = 8'b00000100;
661
                default:    pick_way = 8'b00001000;
662
            endcase
663
            end
664
    end
665
    endfunction
666
 
667
end
668
endgenerate
669
 
670
 
671
// ========================================================
672
// Debug WB bus - not synthesizable
673
// ========================================================
674
//synopsys translate_off
675
wire    [(6*8)-1:0]     xSOURCE_SEL;
676
wire    [(20*8)-1:0]    xC_STATE;
677
 
678
assign xSOURCE_SEL = source_sel[C_CORE]            ? "C_CORE"           :
679
                     source_sel[C_INIT]            ? "C_INIT"           :
680
                     source_sel[C_FILL]            ? "C_FILL"           :
681
                     source_sel[C_INVA]            ? "C_INVA"           :
682
                                                     "UNKNON"           ;
683
 
684
assign xC_STATE    = c_state == CS_INIT            ? "CS_INIT"          :
685
                     c_state == CS_IDLE            ? "CS_IDLE"          :
686
                     c_state == CS_FILL0           ? "CS_FILL0"         :
687
                     c_state == CS_FILL1           ? "CS_FILL1"         :
688
                     c_state == CS_FILL2           ? "CS_FILL2"         :
689
                     c_state == CS_FILL3           ? "CS_FILL3"         :
690
                     c_state == CS_FILL4           ? "CS_FILL4"         :
691
                     c_state == CS_FILL_COMPLETE   ? "CS_FILL_COMPLETE" :
692
                     c_state == CS_EX_DELETE       ? "CS_EX_DELETE"     :
693
                     c_state == CS_TURN_AROUND     ? "CS_TURN_AROUND"   :
694
                     c_state == CS_WRITE_HIT1      ? "CS_WRITE_HIT1"    :
695
                                                     "UNKNOWN"          ;
696
 
697
 
698
generate
699
if ( WAYS == 2 ) begin : check_hit_2ways
700
 
701
    always @( posedge i_clk )
702
        if ( (data_hit_way[0] + data_hit_way[1] ) > 4'd1 )
703
            begin
704
            `TB_ERROR_MESSAGE
705
            $display("Hit in more than one cache ways!");
706
            end
707
 
708
end
709
else if ( WAYS == 3 ) begin : check_hit_3ways
710
 
711
    always @( posedge i_clk )
712
        if ( (data_hit_way[0] + data_hit_way[1] + data_hit_way[2] ) > 4'd1 )
713
            begin
714
            `TB_ERROR_MESSAGE
715
            $display("Hit in more than one cache ways!");
716
            end
717
 
718
end
719
else if ( WAYS == 4 ) begin : check_hit_4ways
720
 
721
    always @( posedge i_clk )
722
        if ( (data_hit_way[0] + data_hit_way[1] +
723
              data_hit_way[2] + data_hit_way[3] ) > 4'd1 )
724
            begin
725
            `TB_ERROR_MESSAGE
726
            $display("Hit in more than one cache ways!");
727
            end
728
 
729
end
730
else if ( WAYS == 8 )  begin : check_hit_8ways
731
 
732
    always @( posedge i_clk )
733
        if ( (data_hit_way[0] + data_hit_way[1] +
734
              data_hit_way[2] + data_hit_way[3] +
735
              data_hit_way[4] + data_hit_way[5] +
736
              data_hit_way[6] + data_hit_way[7] ) > 4'd1 )
737
            begin
738
            `TB_ERROR_MESSAGE
739
            $display("Hit in more than one cache ways!");
740
            end
741
 
742
end
743
else begin : check_hit_nways
744
 
745
    initial
746
        begin
747
        `TB_ERROR_MESSAGE
748
        $display("Unsupported number of ways %0d", WAYS);
749
        $display("Set A25_ICACHE_WAYS in a25_config_defines.v to either 2,3,4 or 8");
750
        end
751
 
752
end
753
endgenerate
754
 
755
//synopsys translate_on
756
 
757
endmodule
758
 

powered by: WebSVN 2.1.0

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