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

Subversion Repositories altor32

[/] [altor32/] [trunk/] [rtl/] [cpu/] [altor32_icache.v] - Blame information for rev 40

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 ultra_embe
//-----------------------------------------------------------------
2
//                           AltOR32 
3
//                Alternative Lightweight OpenRisc 
4 36 ultra_embe
//                            V2.1
5 27 ultra_embe
//                     Ultra-Embedded.com
6 36 ultra_embe
//                   Copyright 2011 - 2014
7 27 ultra_embe
//
8
//               Email: admin@ultra-embedded.com
9
//
10
//                       License: LGPL
11
//-----------------------------------------------------------------
12
//
13 37 ultra_embe
// Copyright (C) 2011 - 2014 Ultra-Embedded.com
14 27 ultra_embe
//
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
// Includes
40
//-----------------------------------------------------------------
41
`include "altor32_defs.v"
42
 
43
//-----------------------------------------------------------------
44
// Module - Instruction Cache
45
//-----------------------------------------------------------------
46 32 ultra_embe
module altor32_icache
47 27 ultra_embe
(
48
    input                       clk_i /*verilator public*/,
49
    input                       rst_i /*verilator public*/,
50
 
51
    // Processor interface
52
    input                       rd_i /*verilator public*/,
53
    input [31:0]                pc_i /*verilator public*/,
54
    output [31:0]               instruction_o /*verilator public*/,
55
    output                      valid_o /*verilator public*/,
56
    input                       invalidate_i /*verilator public*/,
57
 
58 32 ultra_embe
    // Memory interface
59 37 ultra_embe
    output [31:0]               wbm_addr_o /*verilator public*/,
60 32 ultra_embe
    input [31:0]                wbm_dat_i /*verilator public*/,
61 37 ultra_embe
    output [2:0]                wbm_cti_o /*verilator public*/,
62
    output                      wbm_cyc_o /*verilator public*/,
63
    output                      wbm_stb_o /*verilator public*/,
64 32 ultra_embe
    input                       wbm_stall_i/*verilator public*/,
65
    input                       wbm_ack_i/*verilator public*/
66 27 ultra_embe
);
67
 
68
//-----------------------------------------------------------------
69
// Params
70
//-----------------------------------------------------------------
71
parameter BOOT_VECTOR               = 32'h00000000;
72
 
73 40 ultra_embe
// Option: Number of ways (supports 1 or 2)
74
parameter CACHE_NUM_WAYS            = 1;
75
 
76
// Option: Number of cache lines (2^param) * line_size_bytes = cache size
77
parameter CACHE_LINE_ADDR_WIDTH     = 8 - (CACHE_NUM_WAYS-1); /* 256 lines total across all ways */
78
 
79 27 ultra_embe
parameter CACHE_LINE_SIZE_WIDTH     = 5; /* 5-bits -> 32 entries */
80 40 ultra_embe
parameter CACHE_LINE_SIZE_BYTES     = 2 ** CACHE_LINE_SIZE_WIDTH; /* 32 bytes / 8 words per line */
81
 
82
parameter CACHE_TAG_ENTRIES         = 2 ** CACHE_LINE_ADDR_WIDTH ; /* 128 tag entries */
83
parameter CACHE_DSIZE               = CACHE_NUM_WAYS * (2 ** CACHE_LINE_ADDR_WIDTH) * CACHE_LINE_SIZE_BYTES; /* 8KB data */
84 27 ultra_embe
parameter CACHE_DWIDTH              = CACHE_LINE_ADDR_WIDTH + CACHE_LINE_SIZE_WIDTH - 2; /* 10-bits */
85
 
86
parameter CACHE_TAG_WIDTH           = 16; /* 16-bit tag entry size */
87 40 ultra_embe
parameter CACHE_TAG_STAT_BITS       = 1 + (CACHE_NUM_WAYS-1);
88 27 ultra_embe
 
89 40 ultra_embe
parameter CACHE_TAG_LINE_ADDR_WIDTH = CACHE_TAG_WIDTH - CACHE_TAG_STAT_BITS; /* 15 bits of data (tag entry size minus valid / LRU bit) */
90
 
91 27 ultra_embe
parameter CACHE_TAG_ADDR_LOW        = CACHE_LINE_SIZE_WIDTH + CACHE_LINE_ADDR_WIDTH;
92
parameter CACHE_TAG_ADDR_HIGH       = CACHE_TAG_LINE_ADDR_WIDTH + CACHE_LINE_SIZE_WIDTH + CACHE_LINE_ADDR_WIDTH - 1;
93
 
94
// Tag fields
95
parameter CACHE_TAG_VALID_BIT       = 15;
96 40 ultra_embe
parameter CACHE_TAG_LRU_BIT         = 14;   // If CACHE_NUM_WAYS > 1
97
parameter CACHE_TAG_ADDR_BITS       = CACHE_TAG_WIDTH - CACHE_TAG_STAT_BITS;
98 27 ultra_embe
 
99
//  31          16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
100
// |--------------|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
101 40 ultra_embe
//     +-----------------+  +-------------------+   +-----------+      
102
//     Tag entry                    Line address         Address 
103
//       (14/15-bits)               (7/8-bits)           within line 
104 27 ultra_embe
//                                                       (5-bits)
105
 
106
//-----------------------------------------------------------------
107
// Registers / Wires
108
//-----------------------------------------------------------------
109 32 ultra_embe
 
110
// Tag read / write data
111 37 ultra_embe
reg                             tag_wr_r;
112 40 ultra_embe
wire [CACHE_TAG_WIDTH-1:0]      tag_out0_w;
113
reg  [CACHE_TAG_WIDTH-1:0]      tag_in0_r;
114
wire [CACHE_TAG_WIDTH-1:0]      tag_out1_w;
115
reg  [CACHE_TAG_WIDTH-1:0]      tag_in1_r;
116 27 ultra_embe
 
117 32 ultra_embe
// Tag address
118 37 ultra_embe
wire [CACHE_LINE_ADDR_WIDTH-1:0] tag_address_w;
119 32 ultra_embe
 
120
// Data memory read / write
121 37 ultra_embe
wire [CACHE_DWIDTH-1:0]         address_rd_w;
122
wire [CACHE_DWIDTH-1:0]         address_wr_w;
123 27 ultra_embe
 
124 40 ultra_embe
wire                            cache_wr0_w;
125
wire                            cache_wr1_w;
126
 
127
reg                             way_update_q;
128
 
129 32 ultra_embe
// Current / Miss PC
130 37 ultra_embe
reg [31:0]                      last_pc_q;
131
reg [31:0]                      miss_pc_q;
132 27 ultra_embe
 
133 32 ultra_embe
// Flush state
134 37 ultra_embe
reg                             flush_q;
135
reg [CACHE_LINE_ADDR_WIDTH-1:0] flush_addr_q;
136
reg                             flush_wr_q;
137 27 ultra_embe
 
138 32 ultra_embe
// Other state
139 37 ultra_embe
reg                             read_while_busy_q;
140 27 ultra_embe
 
141
// Current state
142
parameter STATE_CHECK       = 0;
143
parameter STATE_FETCH       = 1;
144
parameter STATE_WAIT        = 2;
145 36 ultra_embe
parameter STATE_FLUSH       = 3;
146 37 ultra_embe
reg [1:0]                   state_q;
147 27 ultra_embe
 
148 32 ultra_embe
// Tag address from input PC or flopped version of it
149 37 ultra_embe
assign tag_address_w      = (state_q != STATE_CHECK) ?
150
                          miss_pc_q[CACHE_LINE_ADDR_WIDTH + CACHE_LINE_SIZE_WIDTH - 1:CACHE_LINE_SIZE_WIDTH] :
151 32 ultra_embe
                          pc_i[CACHE_LINE_ADDR_WIDTH + CACHE_LINE_SIZE_WIDTH - 1:CACHE_LINE_SIZE_WIDTH];
152 27 ultra_embe
 
153 32 ultra_embe
// Cache read address
154 37 ultra_embe
assign address_rd_w   = pc_i[CACHE_LINE_ADDR_WIDTH + CACHE_LINE_SIZE_WIDTH - 1:2];
155 27 ultra_embe
 
156 32 ultra_embe
// Cache miss output if requested PC is not in the tag memory
157 40 ultra_embe
wire miss0_w               = ~tag_out0_w[CACHE_TAG_VALID_BIT] |
158
                            (last_pc_q[CACHE_TAG_ADDR_HIGH:CACHE_TAG_ADDR_LOW] != tag_out0_w[CACHE_TAG_ADDR_BITS-1:0]);
159 32 ultra_embe
 
160 40 ultra_embe
wire miss1_w               = ~tag_out1_w[CACHE_TAG_VALID_BIT] |
161
                            (last_pc_q[CACHE_TAG_ADDR_HIGH:CACHE_TAG_ADDR_LOW] != tag_out1_w[CACHE_TAG_ADDR_BITS-1:0]);
162
 
163 36 ultra_embe
// Stall the CPU if cache state machine is not idle!
164 37 ultra_embe
wire busy_w               = (state_q != STATE_CHECK) | read_while_busy_q;
165 36 ultra_embe
 
166 32 ultra_embe
// Cache output valid
167 40 ultra_embe
assign valid_o            = busy_w ? 1'b0 : ~(miss0_w & miss1_w);
168 27 ultra_embe
 
169 32 ultra_embe
// Flushing: Last line to flush
170 37 ultra_embe
wire flush_last_w         = (flush_addr_q == {CACHE_LINE_ADDR_WIDTH{1'b0}});
171 32 ultra_embe
 
172
// Is this a cache miss?
173 40 ultra_embe
wire cache_miss_w         = miss0_w & miss1_w &     // Tag lookup failed
174 37 ultra_embe
                            !rd_i &                 // NOT new read request cycle
175
                            !read_while_busy_q &    // NOT pending read whilst busy
176
                            !flush_q &              // NOT flush request
177
                            !invalidate_i;
178 32 ultra_embe
 
179 37 ultra_embe
wire        mem_fetch_w = (state_q == STATE_CHECK) & cache_miss_w;
180
wire [31:0] mem_data_w;
181
wire [31:0] mem_resp_addr_w;
182
wire        mem_valid_w;
183
wire        mem_final_w;
184
 
185 27 ultra_embe
//-----------------------------------------------------------------
186 32 ultra_embe
// Next State Logic
187 27 ultra_embe
//-----------------------------------------------------------------
188 37 ultra_embe
reg [1:0] next_state_r;
189 32 ultra_embe
always @ *
190
begin
191 37 ultra_embe
    next_state_r = state_q;
192 27 ultra_embe
 
193 37 ultra_embe
    case (state_q)
194 32 ultra_embe
 
195
    //-----------------------------------------
196
    // CHECK - check cache for hit or miss
197
    //-----------------------------------------
198
    STATE_CHECK :
199
    begin
200
        // Cache flush request pending?
201 37 ultra_embe
        if (flush_q || invalidate_i)
202 32 ultra_embe
            next_state_r    = STATE_FLUSH;
203
        // Cache miss (& new read request not pending)
204 37 ultra_embe
        else if (cache_miss_w)
205 32 ultra_embe
            next_state_r    = STATE_FETCH;
206
        // Cache hit (or new read request)
207
        else
208
            next_state_r    = STATE_CHECK;
209
    end
210
    //-----------------------------------------
211
    // FETCH - Fetch row from memory
212
    //-----------------------------------------
213
    STATE_FETCH :
214
    begin
215
        // Line fetch complete?
216 37 ultra_embe
        if (mem_final_w)
217 32 ultra_embe
           next_state_r = STATE_WAIT;
218
    end
219
    //-----------------------------------------
220
    // FLUSH - Invalidate tag memory
221
    //-----------------------------------------
222
    STATE_FLUSH :
223
    begin
224 37 ultra_embe
        if (flush_last_w)
225
            next_state_r = STATE_CHECK;
226 32 ultra_embe
        else
227
            next_state_r = STATE_FLUSH;
228 36 ultra_embe
    end
229 32 ultra_embe
    //-----------------------------------------
230
    // WAIT - Wait cycle
231
    //-----------------------------------------
232
    STATE_WAIT :
233
        next_state_r = STATE_CHECK;
234
    default:
235
        ;
236
   endcase
237
end
238
 
239
// Update state
240 27 ultra_embe
always @ (posedge rst_i or posedge clk_i )
241
begin
242
   if (rst_i == 1'b1)
243 37 ultra_embe
        state_q   <= STATE_FLUSH;
244 32 ultra_embe
   else
245 37 ultra_embe
        state_q   <= next_state_r;
246 32 ultra_embe
end
247
 
248
//-----------------------------------------------------------------
249 40 ultra_embe
// Select way to be replaced
250
//-----------------------------------------------------------------
251
reg lru_way_r;
252
 
253
// 2-Way
254
generate
255
if (CACHE_NUM_WAYS >= 2)
256
begin: LRU_SELECT
257
    always @ *
258
    begin
259
        if (tag_out0_w[CACHE_TAG_LRU_BIT])
260
            lru_way_r = 1'b0;
261
        else
262
            lru_way_r = 1'b1;
263
    end
264
end
265
// 1-Way
266
else
267
begin: LRU_FIXED
268
    wire lru_way_w = 1'b0;
269
    always @ *
270
        lru_way_r = lru_way_w;
271
end
272
endgenerate
273
 
274
//-----------------------------------------------------------------
275 37 ultra_embe
// Flop request details
276 32 ultra_embe
//-----------------------------------------------------------------
277 40 ultra_embe
reg [CACHE_LINE_ADDR_WIDTH-1:0] tag_address_q;
278
 
279 32 ultra_embe
always @ (posedge rst_i or posedge clk_i )
280
begin
281
   if (rst_i == 1'b1)
282 27 ultra_embe
   begin
283 40 ultra_embe
        miss_pc_q       <= BOOT_VECTOR + `VECTOR_RESET;
284
        last_pc_q       <= 32'h00000000;
285
 
286
        tag_address_q   <= {CACHE_LINE_ADDR_WIDTH{1'b0}};
287
        way_update_q    <= 1'b0;
288 32 ultra_embe
   end
289
   else
290
   begin
291 40 ultra_embe
        last_pc_q       <= pc_i;
292
        tag_address_q   <= tag_address_w;
293 27 ultra_embe
 
294 37 ultra_embe
        case (state_q)
295 32 ultra_embe
 
296
        //-----------------------------------------
297
        // CHECK - check cache for hit or miss
298
        //-----------------------------------------
299
        STATE_CHECK :
300
        begin
301 37 ultra_embe
            // Cache hit (or new read request), store fetch PC
302
            if (!cache_miss_w)
303 40 ultra_embe
            begin
304 37 ultra_embe
                miss_pc_q   <= pc_i;
305 40 ultra_embe
            end
306
            // Cache miss
307
            else
308
            begin
309
                // Select line way to replace
310
                way_update_q <= lru_way_r;
311
            end
312
        end
313 32 ultra_embe
        default:
314
            ;
315
       endcase
316
   end
317
end
318
 
319
//-----------------------------------------------------------------
320 37 ultra_embe
// Detect new read request whilst busy
321 32 ultra_embe
//-----------------------------------------------------------------
322
always @ (posedge rst_i or posedge clk_i )
323
begin
324
   if (rst_i == 1'b1)
325 37 ultra_embe
   begin
326
        read_while_busy_q <= 1'b0;
327 32 ultra_embe
   end
328
   else
329
   begin
330 37 ultra_embe
        case (state_q)
331 32 ultra_embe
        //-----------------------------------------
332 37 ultra_embe
        // CHECK - Check cache for hit or miss
333 32 ultra_embe
        //-----------------------------------------
334
        STATE_CHECK :
335
        begin
336 37 ultra_embe
            read_while_busy_q <= 1'b0;
337
        end
338 32 ultra_embe
        //-----------------------------------------
339 37 ultra_embe
        // OTHER - Fetching, flushing, waiting
340 32 ultra_embe
        //-----------------------------------------
341 37 ultra_embe
        default:
342 32 ultra_embe
        begin
343 37 ultra_embe
            // New request whilst cache busy?
344
            if (rd_i)
345
                read_while_busy_q <= 1'b1;
346
        end
347
        endcase
348 32 ultra_embe
   end
349
end
350
 
351
//-----------------------------------------------------------------
352 37 ultra_embe
// Cache Tag Write
353 32 ultra_embe
//-----------------------------------------------------------------
354 37 ultra_embe
always @ *
355 32 ultra_embe
begin
356 40 ultra_embe
    tag_in0_r    = tag_out0_w;
357
    tag_in1_r    = tag_out1_w;
358
    tag_wr_r     = 1'b0;
359 27 ultra_embe
 
360 37 ultra_embe
    case (state_q)
361 27 ultra_embe
 
362 37 ultra_embe
    //-----------------------------------------
363
    // CHECK - check cache for hit or miss
364
    //-----------------------------------------
365
    STATE_CHECK :
366
    begin
367
        // Cache miss (& new read request not pending)
368
        if (cache_miss_w)
369 32 ultra_embe
        begin
370 37 ultra_embe
            // Update tag memory with this line's details
371 40 ultra_embe
            if (lru_way_r)
372
            begin
373
                tag_in1_r[CACHE_TAG_ADDR_BITS-1:0] = miss_pc_q[CACHE_TAG_ADDR_HIGH:CACHE_TAG_ADDR_LOW];
374
                tag_in1_r[CACHE_TAG_VALID_BIT]     = 1'b1;
375
 
376
                if (CACHE_NUM_WAYS >= 2)
377
                begin
378
                    tag_in1_r[CACHE_TAG_LRU_BIT]   = 1'b0;
379
                    tag_in0_r[CACHE_TAG_LRU_BIT]   = 1'b1;
380
                end
381
            end
382
            else
383
            begin
384
                tag_in0_r[CACHE_TAG_ADDR_BITS-1:0] = miss_pc_q[CACHE_TAG_ADDR_HIGH:CACHE_TAG_ADDR_LOW];
385
                tag_in0_r[CACHE_TAG_VALID_BIT]     = 1'b1;
386
 
387
                if (CACHE_NUM_WAYS >= 2)
388
                begin
389
                    tag_in0_r[CACHE_TAG_LRU_BIT]   = 1'b0;
390
                    tag_in1_r[CACHE_TAG_LRU_BIT]   = 1'b1;
391
                end
392
            end
393
 
394 37 ultra_embe
            tag_wr_r    = 1'b1;
395 32 ultra_embe
        end
396 40 ultra_embe
        // Update LRU (if possible)
397
        else if ((tag_address_q == tag_address_w) && (CACHE_NUM_WAYS >= 2))
398
        begin
399
            // Hit Way 0
400
            if (!miss0_w)
401
            begin
402
                // Least recently used way is 1
403
                tag_in1_r[CACHE_TAG_LRU_BIT] = 1'b1;
404
                tag_in0_r[CACHE_TAG_LRU_BIT] = 1'b0;
405
            end
406
            // Hit Way 1
407
            else
408
            begin
409
                // Least recently used way is 0
410
                tag_in0_r[CACHE_TAG_LRU_BIT] = 1'b1;
411
                tag_in1_r[CACHE_TAG_LRU_BIT] = 1'b0;
412
            end
413
 
414
            tag_wr_r    = 1'b1;
415
        end
416 37 ultra_embe
    end
417
    default:
418
        ;
419
   endcase
420 32 ultra_embe
end
421 27 ultra_embe
 
422 32 ultra_embe
//-----------------------------------------------------------------
423 37 ultra_embe
// Flush Logic
424 32 ultra_embe
//-----------------------------------------------------------------
425 37 ultra_embe
reg                             flush_r;
426
reg [CACHE_LINE_ADDR_WIDTH-1:0] flush_addr_r;
427
reg                             flush_wr_r;
428 27 ultra_embe
 
429 37 ultra_embe
always @ *
430 32 ultra_embe
begin
431 37 ultra_embe
    flush_wr_r   = 1'b0;
432
    flush_addr_r = flush_addr_q;
433
    flush_r      = flush_q;
434
 
435
    case (state_q)
436 32 ultra_embe
 
437 37 ultra_embe
    //-----------------------------------------
438
    // CHECK - Check cache for hit or miss
439
    //-----------------------------------------
440
    STATE_CHECK :
441
    begin
442
        // Cache flush request pending?
443
        if (flush_q || invalidate_i)
444 32 ultra_embe
        begin
445 37 ultra_embe
            flush_r         = 1'b0;
446
            flush_addr_r    = {CACHE_LINE_ADDR_WIDTH{1'b1}};
447
            flush_wr_r      = 1'b1;
448 32 ultra_embe
        end
449 37 ultra_embe
    end
450
    //-----------------------------------------
451
    // FLUSH - Invalidate tag memory
452
    //-----------------------------------------
453
    STATE_FLUSH :
454
    begin
455
        flush_addr_r  = flush_addr_q - 1;
456
        flush_wr_r    = 1'b1;
457
    end
458
    //-----------------------------------------
459
    // OTHER - Fetching / wait cycles
460
    //-----------------------------------------
461
    default:
462
    begin
463
        // Latch invalidate request even if can't be actioned now...
464
        if (invalidate_i)
465
            flush_r     = 1'b1;
466
    end
467
    endcase
468 27 ultra_embe
end
469
 
470 32 ultra_embe
always @ (posedge rst_i or posedge clk_i )
471
begin
472
   if (rst_i == 1'b1)
473 37 ultra_embe
   begin
474
        flush_addr_q    <= {CACHE_LINE_ADDR_WIDTH{1'b1}};
475
        flush_wr_q      <= 1'b0;
476
        flush_q         <= 1'b0;
477
   end
478 32 ultra_embe
   else
479
   begin
480 37 ultra_embe
        flush_addr_q    <= flush_addr_r;
481
        flush_wr_q      <= flush_wr_r;
482
        flush_q         <= flush_r;
483 32 ultra_embe
   end
484
end
485
 
486 27 ultra_embe
//-----------------------------------------------------------------
487 37 ultra_embe
// External Mem Access
488 27 ultra_embe
//-----------------------------------------------------------------
489 37 ultra_embe
altor32_wb_fetch
490
u_wb
491
(
492
    .clk_i(clk_i),
493
    .rst_i(rst_i),
494 32 ultra_embe
 
495 37 ultra_embe
    // Request
496
    .fetch_i(mem_fetch_w),
497
    .burst_i(1'b1),
498
    .address_i(miss_pc_q),
499 32 ultra_embe
 
500 37 ultra_embe
    // Response
501
    .resp_addr_o(mem_resp_addr_w),
502
    .data_o(mem_data_w),
503
    .valid_o(mem_valid_w),
504
    .final_o(mem_final_w),
505
 
506
    // Wishbone interface
507
    .wbm_addr_o(wbm_addr_o),
508
    .wbm_dat_i(wbm_dat_i),
509
    .wbm_cti_o(wbm_cti_o),
510
    .wbm_cyc_o(wbm_cyc_o),
511
    .wbm_stb_o(wbm_stb_o),
512
    .wbm_stall_i(wbm_stall_i),
513
    .wbm_ack_i(wbm_ack_i)
514
);
515
 
516 32 ultra_embe
//-----------------------------------------------------------------
517
// Tag memory
518
//-----------------------------------------------------------------
519 40 ultra_embe
wire [(CACHE_NUM_WAYS*CACHE_TAG_WIDTH)-1:0] tag_in;
520
wire [(CACHE_NUM_WAYS*CACHE_TAG_WIDTH)-1:0] tag_out;
521
 
522
altor32_ram_dp
523 27 ultra_embe
#(
524 40 ultra_embe
    .WIDTH(CACHE_TAG_WIDTH * CACHE_NUM_WAYS),
525 27 ultra_embe
    .SIZE(CACHE_LINE_ADDR_WIDTH)
526
)
527 40 ultra_embe
u_tag_mem
528 27 ultra_embe
(
529 32 ultra_embe
    // Tag read/write port
530 27 ultra_embe
    .aclk_i(clk_i),
531 40 ultra_embe
    .adat_o(tag_out),
532
    .adat_i(tag_in),
533 37 ultra_embe
    .aadr_i(tag_address_w),
534
    .awr_i(tag_wr_r),
535 27 ultra_embe
 
536 32 ultra_embe
    // Tag invalidate port
537 27 ultra_embe
    .bclk_i(clk_i),
538 37 ultra_embe
    .badr_i(flush_addr_q),
539 27 ultra_embe
    .bdat_o(/*open*/),
540 40 ultra_embe
    .bdat_i({(CACHE_NUM_WAYS*CACHE_TAG_WIDTH){1'b0}}),
541
    .bwr_i(flush_wr_q)
542 27 ultra_embe
);
543 32 ultra_embe
 
544 40 ultra_embe
// 2-Way
545
generate
546
if (CACHE_NUM_WAYS >= 2)
547
begin: TAG_2WAY
548
    assign tag_in                   = {tag_in1_r, tag_in0_r};
549
    assign {tag_out1_w, tag_out0_w} = tag_out;
550
end
551
// 1-Way
552
else
553
begin: TAG_1WAY
554
    assign tag_in       = tag_in0_r;
555
    assign tag_out0_w   = tag_out;
556
    assign tag_out1_w   = {(CACHE_TAG_WIDTH){1'b0}};
557
end
558
endgenerate
559
 
560 32 ultra_embe
//-----------------------------------------------------------------
561 27 ultra_embe
// Data memory
562 32 ultra_embe
//-----------------------------------------------------------------
563 40 ultra_embe
wire [31:0] way0_instruction_w /*verilator public*/;
564
wire [31:0] way1_instruction_w /*verilator public*/;
565
 
566
// Way 0 Instruction Memory
567
altor32_ram_dp
568 27 ultra_embe
#(
569
    .WIDTH(32),
570
    .SIZE(CACHE_DWIDTH)
571
)
572 40 ultra_embe
u2_data_way0
573 27 ultra_embe
(
574 32 ultra_embe
    // Data read port
575 40 ultra_embe
    .aclk_i(clk_i),
576
    .aadr_i(address_rd_w),
577
    .adat_o(way0_instruction_w),
578
    .adat_i(32'h00),
579
    .awr_i(1'b0),
580
 
581
    // Data write port
582
    .bclk_i(clk_i),
583
    .badr_i(address_wr_w),
584
    .bdat_o(/*open*/),
585
    .bdat_i(mem_data_w),
586
    .bwr_i(cache_wr0_w)
587
);
588
 
589
// Way 1 Instruction Memory
590
altor32_ram_dp
591
#(
592
    .WIDTH(32),
593
    .SIZE(CACHE_DWIDTH)
594
)
595
u2_data_way1
596
(
597
    // Data read port
598 27 ultra_embe
    .aclk_i(clk_i),
599 37 ultra_embe
    .aadr_i(address_rd_w),
600 40 ultra_embe
    .adat_o(way1_instruction_w),
601 27 ultra_embe
    .adat_i(32'h00),
602
    .awr_i(1'b0),
603
 
604 32 ultra_embe
    // Data write port
605 27 ultra_embe
    .bclk_i(clk_i),
606 37 ultra_embe
    .badr_i(address_wr_w),
607 27 ultra_embe
    .bdat_o(/*open*/),
608 37 ultra_embe
    .bdat_i(mem_data_w),
609 40 ultra_embe
    .bwr_i(cache_wr1_w)
610 27 ultra_embe
);
611
 
612 40 ultra_embe
// Select between ways for result
613
assign instruction_o = (miss0_w == 1'b0) ? way0_instruction_w : way1_instruction_w;
614
 
615 36 ultra_embe
// Write to cache on wishbone response
616 37 ultra_embe
assign address_wr_w = {miss_pc_q[CACHE_LINE_ADDR_WIDTH + CACHE_LINE_SIZE_WIDTH - 1:CACHE_LINE_SIZE_WIDTH], mem_resp_addr_w[CACHE_LINE_SIZE_WIDTH-1:2]};
617 36 ultra_embe
 
618 40 ultra_embe
assign cache_wr0_w = (state_q == STATE_FETCH) & mem_valid_w & ~way_update_q;
619
assign cache_wr1_w = (state_q == STATE_FETCH) & mem_valid_w & way_update_q;
620 36 ultra_embe
 
621 27 ultra_embe
endmodule

powered by: WebSVN 2.1.0

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