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

Subversion Repositories altor32

[/] [altor32/] [trunk/] [rtl/] [cpu/] [altor32_dcache.v] - Blame information for rev 32

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

Line No. Rev Author Line
1 27 ultra_embe
//-----------------------------------------------------------------
2
//                           AltOR32 
3
//                Alternative Lightweight OpenRisc 
4
//                            V2.0
5
//                     Ultra-Embedded.com
6
//                   Copyright 2011 - 2013
7
//
8
//               Email: admin@ultra-embedded.com
9
//
10
//                       License: LGPL
11
//-----------------------------------------------------------------
12
//
13
// Copyright (C) 2011 - 2013 Ultra-Embedded.com
14
//
15
// This source file may be used and distributed without         
16
// restriction provided that this copyright statement is not    
17
// removed from the file and that any derivative work contains  
18
// the original copyright notice and the associated disclaimer. 
19
//
20
// This source file is free software; you can redistribute it   
21
// and/or modify it under the terms of the GNU Lesser General   
22
// Public License as published by the Free Software Foundation; 
23
// either version 2.1 of the License, or (at your option) any   
24
// later version.
25
//
26
// This source is distributed in the hope that it will be       
27
// useful, but WITHOUT ANY WARRANTY; without even the implied   
28
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      
29
// PURPOSE.  See the GNU Lesser General Public License for more 
30
// details.
31
//
32
// You should have received a copy of the GNU Lesser General    
33
// Public License along with this source; if not, write to the 
34
// Free Software Foundation, Inc., 59 Temple Place, Suite 330, 
35
// Boston, MA  02111-1307  USA
36
//-----------------------------------------------------------------
37
 
38
//-----------------------------------------------------------------
39
// Module - Data Cache (write back)
40
//-----------------------------------------------------------------
41
module altor32_dcache
42
(
43
    input           clk_i /*verilator public*/,
44
    input           rst_i /*verilator public*/,
45
 
46
    input           flush_i /*verilator public*/,
47
 
48
    // Input (CPU)
49
    input [31:0]    address_i /*verilator public*/,
50
    output [31:0]   data_o /*verilator public*/,
51
    input [31:0]    data_i /*verilator public*/,
52 32 ultra_embe
    input           we_i /*verilator public*/,
53
    input           stb_i /*verilator public*/,
54
    input [3:0]     sel_i /*verilator public*/,
55
    output          stall_o /*verilator public*/,
56 27 ultra_embe
    output          ack_o /*verilator public*/,
57
 
58
    // Output (Memory)
59
    output [31:0]   mem_addr_o /*verilator public*/,
60
    input [31:0]    mem_data_i /*verilator public*/,
61
    output [31:0]   mem_data_o /*verilator public*/,
62 32 ultra_embe
    output [2:0]    mem_cti_o /*verilator public*/,
63
    output          mem_cyc_o /*verilator public*/,
64
    output          mem_stb_o /*verilator public*/,
65
    output          mem_we_o /*verilator public*/,
66
    output [3:0]    mem_sel_o /*verilator public*/,
67
    input           mem_stall_i/*verilator public*/,
68 27 ultra_embe
    input           mem_ack_i/*verilator public*/
69
);
70
 
71
//-----------------------------------------------------------------
72
// Params
73
//-----------------------------------------------------------------
74
parameter CACHE_LINE_SIZE_WIDTH     = 5; /* 5-bits -> 32 entries */
75
parameter CACHE_LINE_SIZE_BYTES     = 2 ** CACHE_LINE_SIZE_WIDTH; /* 32 bytes / 8 words per line */
76
parameter CACHE_LINE_ADDR_WIDTH     = 8; /* 256 lines */
77
parameter CACHE_LINE_WORDS_IDX_MAX  = CACHE_LINE_SIZE_WIDTH - 2; /* 3-bit = 8 words */
78
parameter CACHE_TAG_ENTRIES         = 2 ** CACHE_LINE_ADDR_WIDTH ; /* 256 tag entries */
79
parameter CACHE_DSIZE               = CACHE_LINE_ADDR_WIDTH * CACHE_LINE_SIZE_BYTES; /* 8KB data */
80
parameter CACHE_DWIDTH              = CACHE_LINE_ADDR_WIDTH + CACHE_LINE_SIZE_WIDTH - 2; /* 11-bits */
81
 
82
parameter CACHE_TAG_WIDTH           = 16; /* 16-bit tag entry size */
83
parameter CACHE_TAG_LINE_ADDR_WIDTH = CACHE_TAG_WIDTH - 2; /* 14 bits of data (tag entry size minus valid/dirty bit) */
84
 
85
parameter CACHE_TAG_ADDR_LOW        = CACHE_LINE_SIZE_WIDTH + CACHE_LINE_ADDR_WIDTH;
86
parameter CACHE_TAG_ADDR_HIGH       = CACHE_TAG_LINE_ADDR_WIDTH + CACHE_LINE_SIZE_WIDTH + CACHE_LINE_ADDR_WIDTH - 1;
87
 
88
// Tag fields
89
parameter CACHE_TAG_DIRTY_BIT       = 14;
90
parameter CACHE_TAG_VALID_BIT       = 15;
91
parameter ADDR_NO_CACHE_BIT         = 25;
92
parameter ADDR_CACHE_BYPASS_BIT     = 31;
93
 
94
//  31          16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
95
// |--------------|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
96
//  +--------------------+   +-------------------+   +-----------+      
97
//    Tag entry                     Line address         Address 
98
//       (15-bits)                    (8-bits)           within line 
99
//                                                       (5-bits)
100
 
101
//-----------------------------------------------------------------
102
// Registers / Wires
103
//-----------------------------------------------------------------
104
wire [CACHE_LINE_ADDR_WIDTH-1:0] tag_entry;
105
wire [CACHE_TAG_WIDTH-1:0]       tag_data_out;
106
reg  [CACHE_TAG_WIDTH-1:0]       tag_data_in;
107
reg                              tag_wr;
108
 
109
wire [CACHE_DWIDTH-1:0]          cache_address;
110
wire [31:0]                      cache_data_r;
111
reg [31:0]                       cache_data_w;
112
reg [3:0]                        cache_wr;
113
 
114
wire [31:2]                      cache_update_addr;
115
wire [31:0]                      cache_update_data_w;
116
wire [31:0]                      cache_update_data_r;
117
wire                             cache_update_wr;
118
 
119
reg                              ack;
120
 
121
reg                              fill;
122
reg                              evict;
123
wire                             done;
124
 
125
wire [31:0]                      data_r;
126 32 ultra_embe
reg                              rd_single;
127
reg [3:0]                        wr_single;
128 27 ultra_embe
 
129
reg                              req_rd;
130
reg [3:0]                        req_wr;
131
reg                              req_ack;
132
reg [31:0]                       req_address;
133 32 ultra_embe
reg [31:0]                       req_data;
134 27 ultra_embe
 
135
reg                              req_flush;
136
reg                              flush_single;
137
 
138
wire [31:0]                      line_address;
139
 
140
wire [31:0]                      muxed_address = (state == STATE_IDLE) ? address_i : req_address;
141
 
142
// Current state
143
parameter STATE_IDLE        = 0;
144
parameter STATE_SINGLE      = 1;
145
parameter STATE_CHECK       = 2;
146
parameter STATE_FETCH       = 3;
147
parameter STATE_WAIT        = 4;
148
parameter STATE_WAIT2       = 5;
149
parameter STATE_WRITE       = 6;
150
parameter STATE_SINGLE_READY= 7;
151
parameter STATE_EVICTING    = 8;
152
parameter STATE_UPDATE      = 9;
153
parameter STATE_FLUSH1      = 10;
154
parameter STATE_FLUSH2      = 11;
155
parameter STATE_FLUSH3      = 12;
156
parameter STATE_FLUSH4      = 13;
157
reg [3:0] state;
158
 
159
assign tag_entry               = muxed_address[CACHE_LINE_ADDR_WIDTH + CACHE_LINE_SIZE_WIDTH - 1:CACHE_LINE_SIZE_WIDTH];
160
assign cache_address           = {tag_entry, muxed_address[CACHE_LINE_SIZE_WIDTH-1:2]};
161
 
162
assign data_o                  = (state == STATE_SINGLE_READY) ? data_r : cache_data_r;
163 32 ultra_embe
assign stall_o                 = (state != STATE_IDLE) | req_flush;
164 27 ultra_embe
 
165
wire valid                     = tag_data_out[CACHE_TAG_VALID_BIT];
166
wire dirty                     = tag_data_out[CACHE_TAG_DIRTY_BIT];
167
 
168
// Access is cacheable?
169
wire cacheable                 = ~muxed_address[ADDR_NO_CACHE_BIT] & ~muxed_address[ADDR_CACHE_BYPASS_BIT];
170
 
171 32 ultra_embe
// Address matches cache tag
172
wire addr_hit                  = (req_address[CACHE_TAG_ADDR_HIGH:CACHE_TAG_ADDR_LOW] == tag_data_out[13:0]);
173
 
174 27 ultra_embe
// Cache hit?
175 32 ultra_embe
wire hit                       = cacheable & valid & addr_hit & (state == STATE_CHECK);
176 27 ultra_embe
 
177
assign ack_o                   = ack | hit;
178
 
179
assign line_address[CACHE_LINE_ADDR_WIDTH + CACHE_LINE_SIZE_WIDTH - 1:CACHE_LINE_SIZE_WIDTH] = tag_entry;
180
assign line_address[CACHE_TAG_ADDR_HIGH:CACHE_TAG_ADDR_LOW] = tag_data_out[13:0];
181
assign line_address[CACHE_LINE_SIZE_WIDTH-1:0] = {CACHE_LINE_SIZE_WIDTH{1'b0}};
182
 
183 32 ultra_embe
 
184 27 ultra_embe
//-----------------------------------------------------------------
185 32 ultra_embe
// Next State Logic
186 27 ultra_embe
//-----------------------------------------------------------------
187 32 ultra_embe
reg [3:0] next_state_r;
188
always @ *
189
begin
190
    next_state_r = state;
191
 
192
    case (state)
193
    //-----------------------------------------
194
    // IDLE
195
    //-----------------------------------------
196
    STATE_IDLE :
197
    begin
198
        // Cache flush request
199
        if (flush_i | req_flush)
200
            next_state_r    = STATE_FLUSH2;
201
        // Read (uncacheable)
202
        else if (stb_i & ~we_i & ~cacheable)
203
            next_state_r    = STATE_SINGLE;
204
        // Read (cacheable)
205
        else if (stb_i & ~we_i)
206
            next_state_r    = STATE_CHECK;
207
        // Write (uncacheable)
208
        else if (stb_i & we_i & ~cacheable)
209
            next_state_r    = STATE_SINGLE;
210
        // Write (cacheable)
211
        else if (stb_i & we_i)
212
            next_state_r    = STATE_WRITE;
213
    end
214
    //-----------------------------------------
215
    // WRITE - Wait for write-thru to complete
216
    //-----------------------------------------
217
    STATE_WRITE :
218
    begin
219
        // Cache hit
220
        if (valid & addr_hit)
221
            next_state_r    = STATE_WAIT2;
222
        // Cache dirty
223
        else if (valid & dirty)
224
            next_state_r    = STATE_EVICTING;
225
        // Cache miss
226
        else
227
            next_state_r    = STATE_UPDATE;
228
    end
229
    //-----------------------------------------
230
    // EVICTING - Evicting cache line
231
    //-----------------------------------------
232
    STATE_EVICTING:
233
    begin
234
        // Data ready from memory?
235
        if (done)
236
        begin
237
            // Evict for read?
238
            if (req_rd)
239
                next_state_r   = STATE_FETCH;
240
            // Evict for write
241
            else
242
                next_state_r   = STATE_UPDATE;
243
        end
244
    end
245
    //-----------------------------------------
246
    // UPDATE - Update fetched cache line
247
    //-----------------------------------------
248
    STATE_UPDATE:
249
    begin
250
        // Data ready from memory?
251
        if (done)
252
            next_state_r    = STATE_WAIT2;
253
    end
254
    //-----------------------------------------
255
    // CHECK - check cache for hit or miss
256
    //-----------------------------------------
257
    STATE_CHECK :
258
    begin
259
        // Cache hit
260
        if (valid & addr_hit)
261
            next_state_r    = STATE_IDLE;
262
        // Cache dirty
263
        else if (valid & dirty)
264
            next_state_r    = STATE_EVICTING;
265
        // Cache miss
266
        else
267
            next_state_r    = STATE_FETCH;
268
    end
269
    //-----------------------------------------
270
    // FETCH_SINGLE - Single access to memory
271
    //-----------------------------------------
272
    STATE_SINGLE:
273
    begin
274
        // Data ready from memory?
275
        if (done)
276
        begin
277
            // Single WRITE?
278
            if (~req_rd)
279
                next_state_r    = STATE_SINGLE_READY;
280
            // Dirty? Write back
281
            else if (valid & dirty & addr_hit)
282
                next_state_r    = STATE_FLUSH4;
283
            // Valid line, invalidate
284
            else if (valid & addr_hit)
285
                next_state_r    = STATE_SINGLE_READY;
286
            else
287
                next_state_r    = STATE_SINGLE_READY;
288
        end
289
    end
290
    //-----------------------------------------
291
    // FETCH - Fetch row from memory
292
    //-----------------------------------------
293
    STATE_FETCH :
294
    begin
295
        // Cache line filled?
296
        if (done)
297
           next_state_r = STATE_WAIT;
298
    end
299
    //-----------------------------------------
300
    // WAIT - Wait cycle
301
    //-----------------------------------------
302
    STATE_WAIT :
303
    begin
304
        // Allow extra wait state to handle write & read collision               
305
        next_state_r    = STATE_WAIT2;
306
    end
307
    //-----------------------------------------
308
    // WAIT2 - Wait cycle
309
    //-----------------------------------------
310
    STATE_WAIT2 :
311
    begin
312
        next_state_r    = STATE_IDLE;
313
    end
314
    //-----------------------------------------
315
    // SINGLE_READY - Uncached access ready
316
    //-----------------------------------------
317
    STATE_SINGLE_READY :
318
    begin
319
        // Allow extra wait state to handle write & read collision               
320
        next_state_r    = STATE_IDLE;
321
    end
322
    //-----------------------------------------
323
    // FLUSHx - Flush dirty lines & invalidate
324
    //-----------------------------------------
325
    STATE_FLUSH1 :
326
    begin
327
        if (req_address[CACHE_LINE_ADDR_WIDTH + CACHE_LINE_SIZE_WIDTH - 1:CACHE_LINE_SIZE_WIDTH] == {CACHE_LINE_ADDR_WIDTH{1'b1}})
328
            next_state_r    = STATE_WAIT;
329
        else
330
            next_state_r    = STATE_FLUSH2;
331
    end
332
    //-----------------------------------------
333
    // FLUSH2 - Wait state
334
    //-----------------------------------------
335
    STATE_FLUSH2 :
336
    begin
337
        // Allow a cycle to read line state
338
        next_state_r    = STATE_FLUSH3;
339
    end
340
    //-----------------------------------------
341
    // FLUSH3 - Check if line dirty & flush
342
    //-----------------------------------------            
343
    STATE_FLUSH3 :
344
    begin
345
        // Dirty line? Evict line first
346
        if (dirty)
347
            next_state_r    = STATE_FLUSH4;
348
        // Not dirty? Just invalidate
349
        else
350
        begin
351
            if (flush_single)
352
                next_state_r    = STATE_WAIT;
353
            else
354
                next_state_r    = STATE_FLUSH1;
355
        end
356
    end
357
    //-----------------------------------------
358
    // FLUSH4 - Wait for line flush to complete
359
    //-----------------------------------------            
360
    STATE_FLUSH4 :
361
    begin
362
        // Cache line filled?
363
        if (done)
364
        begin
365
            if (flush_single)
366
                next_state_r    = STATE_SINGLE_READY;
367
            else
368
                next_state_r    = STATE_FLUSH1;
369
        end
370
    end
371
 
372
    default:
373
        ;
374
   endcase
375
end
376
 
377
// Update state
378 27 ultra_embe
always @ (posedge rst_i or posedge clk_i )
379
begin
380
   if (rst_i == 1'b1)
381 32 ultra_embe
        state   <= STATE_IDLE;
382
   else
383
        state   <= next_state_r;
384
end
385
 
386
//-----------------------------------------------------------------
387
// Tag Write
388
//-----------------------------------------------------------------
389
always @ (posedge rst_i or posedge clk_i )
390
begin
391
   if (rst_i == 1'b1)
392 27 ultra_embe
   begin
393 32 ultra_embe
        tag_data_in     <= 16'b0;
394
        tag_wr          <= 1'b0;
395
   end
396
   else
397
   begin
398
        tag_wr          <= 1'b0;
399
 
400
        case (state)
401
        //-----------------------------------------
402
        // WRITE - Wait for write-thru to complete
403
        //-----------------------------------------
404
        STATE_WRITE :
405
        begin
406
            // Cache hit
407
            if (valid & addr_hit)
408
            begin
409
                // Mark line as dirty
410
                tag_data_in  <= tag_data_out;
411
                tag_data_in[CACHE_TAG_DIRTY_BIT] <= 1'b1;
412
                tag_wr       <= 1'b1;
413
            end
414
            // Cache miss / cache line doesn't require write back
415
            else if (~valid | ~dirty)
416
            begin
417
                // Update tag memory with this line's details   
418
                tag_data_in <= {1'b1, 1'b1, req_address[CACHE_TAG_ADDR_HIGH:CACHE_TAG_ADDR_LOW]};
419
                tag_wr      <= 1'b1;
420
            end
421
        end
422
        //-----------------------------------------
423
        // EVICTING - Evicting cache line
424
        //-----------------------------------------
425
        STATE_EVICTING:
426
        begin
427
            // Data ready from memory?
428
            if (done)
429
            begin
430
                // Update tag memory with this new line's details   
431
                tag_data_in <= {1'b1, 1'b0, req_address[CACHE_TAG_ADDR_HIGH:CACHE_TAG_ADDR_LOW]};
432
                tag_wr      <= 1'b1;
433
            end
434
        end
435
        //-----------------------------------------
436
        // UPDATE - Update fetched cache line
437
        //-----------------------------------------
438
        STATE_UPDATE:
439
        begin
440
            // Data ready from memory?
441
            if (done)
442
            begin
443
                // Mark line as dirty
444
                tag_data_in  <= tag_data_out;
445
                tag_data_in[CACHE_TAG_DIRTY_BIT] <= 1'b1;
446
                tag_wr       <= 1'b1;
447
            end
448
        end
449
        //-----------------------------------------
450
        // CHECK - check cache for hit or miss
451
        //-----------------------------------------
452
        STATE_CHECK :
453
        begin
454
            // Cache hit
455
            if (valid & addr_hit)
456
            begin
457
 
458
            end
459
            // Cache miss / cache line doesn't require write back
460
            else if (~valid | ~dirty)
461
            begin
462
                // Update tag memory with this line's details   
463
                tag_data_in <= {1'b1, 1'b0, req_address[CACHE_TAG_ADDR_HIGH:CACHE_TAG_ADDR_LOW]};
464
                tag_wr      <= 1'b1;
465
            end
466
        end
467
        //-----------------------------------------
468
        // FETCH_SINGLE - Single access to memory
469
        //-----------------------------------------
470
        STATE_SINGLE:
471
        begin
472
            // Data ready from memory?
473
            if (done)
474
            begin
475
                // Single WRITE?
476
                if (~req_rd)
477
                begin
478
                    // Invalidate cached version
479
                    if (valid & addr_hit)
480
                    begin
481
                        tag_data_in  <= tag_data_out;
482
                        tag_data_in[CACHE_TAG_VALID_BIT] <= 1'b0;
483
                        tag_wr       <= 1'b1;
484
                    end
485
                end
486
                // Valid line (not dirty), just invalidate
487
                else if (valid & ~dirty & addr_hit)
488
                begin
489
                    tag_data_in  <= tag_data_out;
490
                    tag_data_in[CACHE_TAG_VALID_BIT] <= 1'b0;
491
                    tag_wr       <= 1'b1;
492
                end
493
            end
494
        end
495
 
496
        //-----------------------------------------
497
        // FLUSH3 - Check if line dirty & flush
498
        //-----------------------------------------            
499
        STATE_FLUSH3 :
500
        begin
501
            // Not dirty? Just invalidate
502
            if (~dirty)
503
            begin
504
                tag_data_in  <= tag_data_out;
505
                tag_data_in[CACHE_TAG_VALID_BIT] <= 1'b0;
506
                tag_wr       <= 1'b1;
507
            end
508
        end
509
        //-----------------------------------------
510
        // FLUSH4 - Wait for line flush to complete
511
        //-----------------------------------------            
512
        STATE_FLUSH4 :
513
        begin
514
            // Cache line filled?
515
            if (done)
516
            begin
517
                // Invalidate line
518
                tag_data_in  <= tag_data_out;
519
                tag_data_in[CACHE_TAG_VALID_BIT] <= 1'b0;
520
                tag_data_in[CACHE_TAG_DIRTY_BIT] <= 1'b0;
521
                tag_wr       <= 1'b1;
522
            end
523
        end
524
        default:
525
            ;
526
       endcase
527
   end
528
end
529
 
530
//-----------------------------------------------------------------
531
// Register requests
532
//-----------------------------------------------------------------
533
always @ (posedge rst_i or posedge clk_i )
534
begin
535
   if (rst_i == 1'b1)
536
   begin
537 27 ultra_embe
        req_address     <= 32'h00000000;
538 32 ultra_embe
        req_data        <= 32'h00000000;
539 27 ultra_embe
        req_ack         <= 1'b0;
540
        req_wr          <= 4'h0;
541
        req_rd          <= 1'b0;
542
        req_flush       <= 1'b0;
543 32 ultra_embe
   end
544
   else
545
   begin
546
        if (flush_i)
547
            req_flush       <= 1'b1;
548
 
549
        case (state)
550
        //-----------------------------------------
551
        // IDLE
552
        //-----------------------------------------
553
        STATE_IDLE :
554
        begin
555
            // Cache flush request
556
            if (flush_i | req_flush)
557
            begin
558
                // Set to first line address
559
                req_address <= 32'h00000000;
560
                req_flush   <= 1'b0;
561
                req_ack     <= 1'b0;
562
            end
563
            // Read (uncacheable)
564
            else if (stb_i & ~we_i & ~cacheable)
565
            begin
566
                // Start read single from memory
567
                req_address <= address_i;
568
                req_address[ADDR_CACHE_BYPASS_BIT] <= 1'b0;
569
                req_rd      <= 1'b1;
570
                req_wr      <= 4'b0;
571
                req_ack     <= 1'b1;
572
            end
573
            // Read (cacheable)
574
            else if (stb_i & ~we_i)
575
            begin
576
                req_address <= address_i;
577
                req_rd      <= 1'b1;
578
                req_wr      <= 4'b0;
579
                req_ack     <= 1'b1;
580
            end
581
            // Write (uncacheable)
582
            else if (stb_i & we_i & ~cacheable)
583
            begin
584
                // Perform write single
585
                req_address <= address_i;
586
                req_address[ADDR_CACHE_BYPASS_BIT] <= 1'b0;
587
                req_data    <= data_i;
588
                req_wr      <= sel_i;
589
                req_rd      <= 1'b0;
590
                req_ack     <= 1'b1;
591
            end
592
            // Write (cacheable)
593
            else if (stb_i & we_i)
594
            begin
595
                req_address <= address_i;
596
                req_data    <= data_i;
597
                req_wr      <= sel_i;
598
                req_rd      <= 1'b0;
599
                req_ack     <= 1'b0;
600
            end
601
        end
602
        //-----------------------------------------
603
        // FLUSHx - Flush dirty lines & invalidate
604
        //-----------------------------------------
605
        STATE_FLUSH1 :
606
        begin
607
            if (req_address[CACHE_LINE_ADDR_WIDTH + CACHE_LINE_SIZE_WIDTH - 1:CACHE_LINE_SIZE_WIDTH] == {CACHE_LINE_ADDR_WIDTH{1'b1}})
608
            begin
609
                req_ack <= 1'b0;
610
            end
611
            else
612
            begin
613
                // Increment flush line address
614
                req_address[CACHE_LINE_ADDR_WIDTH + CACHE_LINE_SIZE_WIDTH - 1:CACHE_LINE_SIZE_WIDTH] <=
615
                req_address[CACHE_LINE_ADDR_WIDTH + CACHE_LINE_SIZE_WIDTH - 1:CACHE_LINE_SIZE_WIDTH] + 1;
616
            end
617
        end
618
        default:
619
            ;
620
       endcase
621
   end
622
end
623
 
624
//-----------------------------------------------------------------
625
// Cache Data Write
626
//-----------------------------------------------------------------
627
always @ (posedge rst_i or posedge clk_i )
628
begin
629
   if (rst_i == 1'b1)
630
   begin
631
        cache_data_w    <= 32'h00000000;
632
        cache_wr        <= 4'b0;
633
   end
634
   else
635
   begin
636
        cache_wr        <= 4'b0;
637
 
638
        case (state)
639
        //-----------------------------------------
640
        // WRITE - Wait for write-thru to complete
641
        //-----------------------------------------
642
        STATE_WRITE :
643
        begin
644
            // Cache hit
645
            if (valid & addr_hit)
646
            begin
647
                // Update line already in cache
648
                cache_data_w <= req_data;
649
                cache_wr     <= req_wr;
650
            end
651
        end
652
        //-----------------------------------------
653
        // UPDATE - Update fetched cache line
654
        //-----------------------------------------
655
        STATE_UPDATE:
656
        begin
657
            // Data ready from memory?
658
            if (done)
659
            begin
660
                // Update line already in cache
661
                cache_data_w <= req_data;
662
                cache_wr     <= req_wr;
663
            end
664
        end
665
        default:
666
            ;
667
       endcase
668
   end
669
end
670
 
671
//-----------------------------------------------------------------
672
// Control
673
//-----------------------------------------------------------------
674
always @ (posedge rst_i or posedge clk_i )
675
begin
676
   if (rst_i == 1'b1)
677
   begin
678
        wr_single       <= 4'h0;
679
        rd_single       <= 1'b0;
680 27 ultra_embe
        flush_single    <= 1'b0;
681
        fill            <= 1'b0;
682
        evict           <= 1'b0;
683
   end
684
   else
685
   begin
686
        fill            <= 1'b0;
687
        evict           <= 1'b0;
688 32 ultra_embe
        wr_single       <= 4'b0;
689
        rd_single       <= 1'b0;
690 27 ultra_embe
 
691
        case (state)
692
 
693
            //-----------------------------------------
694
            // IDLE
695
            //-----------------------------------------
696
            STATE_IDLE :
697 32 ultra_embe
            begin
698
                // Cache flush request
699
                if (flush_i | req_flush)
700
                begin
701
                    // Set to first line address
702
                    flush_single<= 1'b0;
703
                end
704 27 ultra_embe
                // Read (uncacheable)
705 32 ultra_embe
                else if (stb_i & ~we_i & ~cacheable)
706 27 ultra_embe
                begin
707
                    // Start read single from memory
708 32 ultra_embe
                    rd_single     <= 1'b1;
709
                end
710 27 ultra_embe
                // Write (uncacheable)
711 32 ultra_embe
                else if (stb_i & we_i & ~cacheable)
712 27 ultra_embe
                begin
713
                    // Perform write single
714 32 ultra_embe
                    wr_single     <= sel_i;
715
                end
716 27 ultra_embe
            end
717
            //-----------------------------------------
718
            // WRITE - Wait for write-thru to complete
719
            //-----------------------------------------
720
            STATE_WRITE :
721
            begin
722
                // Cache hit
723 32 ultra_embe
                if (valid & addr_hit)
724 27 ultra_embe
                begin
725
 
726
                end
727
                // Cache dirty
728
                else if (valid & dirty)
729
                begin
730
                    // Evict cache line
731
                    evict       <= 1'b1;
732
                end
733
                // Cache miss
734
                else
735
                begin
736
                    // Fill cache line
737
                    fill        <= 1'b1;
738
                end
739
            end
740
            //-----------------------------------------
741
            // EVICTING - Evicting cache line
742
            //-----------------------------------------
743
            STATE_EVICTING:
744
            begin
745
                // Data ready from memory?
746
                if (done)
747
                begin
748
                    // Fill cache line
749
                    fill        <= 1'b1;
750
                end
751 32 ultra_embe
            end
752 27 ultra_embe
            //-----------------------------------------
753
            // CHECK - check cache for hit or miss
754
            //-----------------------------------------
755
            STATE_CHECK :
756
            begin
757
                // Cache hit
758 32 ultra_embe
                if (valid & addr_hit)
759 27 ultra_embe
                begin
760 32 ultra_embe
 
761 27 ultra_embe
                end
762
                // Cache dirty
763
                else if (valid & dirty)
764
                begin
765
                    // Evict cache line
766
                    evict       <= 1'b1;
767
                end
768
                // Cache miss
769
                else
770
                begin
771
                    // Fill cache line
772
                    fill        <= 1'b1;
773
                end
774
            end
775
            //-----------------------------------------
776
            // FETCH_SINGLE - Single access to memory
777
            //-----------------------------------------
778
            STATE_SINGLE:
779
            begin
780
                // Data ready from memory?
781
                if (done)
782
                begin
783
                    // Single WRITE?
784
                    if (~req_rd)
785
                    begin
786 32 ultra_embe
 
787 27 ultra_embe
                    end
788
                    // Dirty? Write back
789 32 ultra_embe
                    else if (valid & dirty & addr_hit)
790 27 ultra_embe
                    begin
791
                        // Evict cache line
792
                        evict       <= 1'b1;
793
                        flush_single<= 1'b1;
794
                    end
795
                end
796 32 ultra_embe
            end
797 27 ultra_embe
            //-----------------------------------------
798
            // FLUSH3 - Check if line dirty & flush
799
            //-----------------------------------------            
800
            STATE_FLUSH3 :
801
            begin
802
                // Dirty line? Evict line first
803
                if (dirty)
804
                begin
805
                    // Evict cache line
806
                    evict       <= 1'b1;
807
                end
808 32 ultra_embe
            end
809
            default:
810
                ;
811
           endcase
812
   end
813
end
814 27 ultra_embe
 
815 32 ultra_embe
//-----------------------------------------------------------------
816
// ACK
817
//-----------------------------------------------------------------
818
always @ (posedge rst_i or posedge clk_i )
819
begin
820
   if (rst_i == 1'b1)
821
        ack     <= 1'b0;
822
   else
823
   begin
824
        ack     <= 1'b0;
825
 
826
        case (state)
827
 
828
        //-----------------------------------------
829
        // IDLE
830
        //-----------------------------------------
831
        STATE_IDLE :
832
        begin
833
            // Write (cacheable), early acknowledge
834
            if (~(flush_i | req_flush) & stb_i & we_i & cacheable)
835
                ack <= 1'b1;
836
        end
837
        //-----------------------------------------
838
        // FETCH_SINGLE - Single access to memory
839
        //-----------------------------------------
840
        STATE_SINGLE:
841
        begin
842
            // Data ready from memory?
843
            if (done)
844 27 ultra_embe
            begin
845 32 ultra_embe
                // Single WRITE?
846
                if (~req_rd)
847
                    ack         <= req_ack;
848
                // Dirty? Write back
849
                else if (valid & dirty & addr_hit)
850 27 ultra_embe
                begin
851
 
852
                end
853 32 ultra_embe
                // Valid line, invalidate
854
                else if (valid & addr_hit)
855
                    ack         <= req_ack;
856
                else
857
                    ack         <= req_ack;
858
            end
859
        end
860
        //-----------------------------------------
861
        // WAIT2 - Wait cycle
862
        //-----------------------------------------
863
        STATE_WAIT2 :
864
        begin
865
            ack     <= req_ack;
866
        end
867
        //-----------------------------------------
868
        // FLUSH4 - Wait for line flush to complete
869
        //-----------------------------------------            
870
        STATE_FLUSH4 :
871
        begin
872
            if (done & flush_single)
873
                ack     <= req_ack;
874
        end
875
        default:
876
            ;
877
       endcase
878 27 ultra_embe
   end
879
end
880
 
881
//-----------------------------------------------------------------
882
// Instantiation
883
//-----------------------------------------------------------------
884
 
885
altor32_dcache_mem_if
886
#(
887
    .CACHE_LINE_SIZE_WIDTH(CACHE_LINE_SIZE_WIDTH),
888
    .CACHE_LINE_WORDS_IDX_MAX(CACHE_LINE_WORDS_IDX_MAX)
889
)
890
u_mem_if
891
(
892
    .clk_i(clk_i),
893
    .rst_i(rst_i),
894
 
895
    // Cache interface
896
    .address_i(muxed_address),
897 32 ultra_embe
    .data_i(req_data),
898 27 ultra_embe
    .data_o(data_r),
899
    .fill_i(fill),
900
    .evict_i(evict),
901
    .evict_addr_i(line_address),
902 32 ultra_embe
    .rd_single_i(rd_single),
903
    .wr_single_i(wr_single),
904 27 ultra_embe
    .done_o(done),
905
 
906
    // Cache memory (fill/evict)
907
    .cache_addr_o(cache_update_addr),
908
    .cache_data_o(cache_update_data_w),
909
    .cache_data_i(cache_update_data_r),
910
    .cache_wr_o(cache_update_wr),
911
 
912
    // Memory interface (slave)
913
    .mem_addr_o(mem_addr_o),
914
    .mem_data_i(mem_data_i),
915
    .mem_data_o(mem_data_o),
916 32 ultra_embe
    .mem_cti_o(mem_cti_o),
917
    .mem_cyc_o(mem_cyc_o),
918
    .mem_stb_o(mem_stb_o),
919
    .mem_we_o(mem_we_o),
920
    .mem_sel_o(mem_sel_o),
921
    .mem_stall_i(mem_stall_i),
922 27 ultra_embe
    .mem_ack_i(mem_ack_i)
923
);
924
 
925
// Tag memory    
926
altor32_ram_sp
927
#(
928
    .WIDTH(CACHE_TAG_WIDTH),
929
    .SIZE(CACHE_LINE_ADDR_WIDTH)
930
)
931
u1_tag_mem
932
(
933
    .clk_i(clk_i),
934
    .dat_o(tag_data_out),
935
    .dat_i(tag_data_in),
936
    .adr_i(tag_entry),
937
    .wr_i(tag_wr)
938
);
939
 
940
// Data memory   
941
altor32_ram_dp
942
#(
943
    .WIDTH(8),
944
    .SIZE(CACHE_DWIDTH)
945
)
946
u2_data_mem0
947
(
948
    .aclk_i(clk_i),
949
    .aadr_i(cache_address),
950
    .adat_o(cache_data_r[7:0]),
951
    .adat_i(cache_data_w[7:0]),
952
    .awr_i(cache_wr[0]),
953
 
954
    .bclk_i(clk_i),
955
    .badr_i(cache_update_addr[CACHE_DWIDTH+2-1:2]),
956
    .bdat_o(cache_update_data_r[7:0]),
957
    .bdat_i(cache_update_data_w[7:0]),
958
    .bwr_i(cache_update_wr)
959
);
960
 
961
altor32_ram_dp
962
#(
963
    .WIDTH(8),
964
    .SIZE(CACHE_DWIDTH)
965
)
966
u2_data_mem1
967
(
968
    .aclk_i(clk_i),
969
    .aadr_i(cache_address),
970
    .adat_o(cache_data_r[15:8]),
971
    .adat_i(cache_data_w[15:8]),
972
    .awr_i(cache_wr[1]),
973
 
974
    .bclk_i(clk_i),
975
    .badr_i(cache_update_addr[CACHE_DWIDTH+2-1:2]),
976
    .bdat_o(cache_update_data_r[15:8]),
977
    .bdat_i(cache_update_data_w[15:8]),
978
    .bwr_i(cache_update_wr)
979
);
980
 
981
altor32_ram_dp
982
#(
983
    .WIDTH(8),
984
    .SIZE(CACHE_DWIDTH)
985
)
986
u2_data_mem2
987
(
988
    .aclk_i(clk_i),
989
    .aadr_i(cache_address),
990
    .adat_o(cache_data_r[23:16]),
991
    .adat_i(cache_data_w[23:16]),
992
    .awr_i(cache_wr[2]),
993
 
994
    .bclk_i(clk_i),
995
    .badr_i(cache_update_addr[CACHE_DWIDTH+2-1:2]),
996
    .bdat_o(cache_update_data_r[23:16]),
997
    .bdat_i(cache_update_data_w[23:16]),
998
    .bwr_i(cache_update_wr)
999
);
1000
 
1001
altor32_ram_dp
1002
#(
1003
    .WIDTH(8),
1004
    .SIZE(CACHE_DWIDTH)
1005
)
1006
u2_data_mem3
1007
(
1008
    .aclk_i(clk_i),
1009
    .aadr_i(cache_address),
1010
    .adat_o(cache_data_r[31:24]),
1011
    .adat_i(cache_data_w[31:24]),
1012
    .awr_i(cache_wr[3]),
1013
 
1014
    .bclk_i(clk_i),
1015
    .badr_i(cache_update_addr[CACHE_DWIDTH+2-1:2]),
1016
    .bdat_o(cache_update_data_r[31:24]),
1017
    .bdat_i(cache_update_data_w[31:24]),
1018
    .bwr_i(cache_update_wr)
1019
);
1020
 
1021
endmodule

powered by: WebSVN 2.1.0

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