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

Subversion Repositories altor32

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

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 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
parameter CACHE_LINE_SIZE_WIDTH     = 5; /* 5-bits -> 32 entries */
74
parameter CACHE_LINE_SIZE_BYTES     = 2 ** CACHE_LINE_SIZE_WIDTH; /* 32 bytes / 4 words per line */
75
parameter CACHE_LINE_ADDR_WIDTH     = 8; /* 256 lines */
76
parameter CACHE_LINE_WORDS_IDX_MAX  = CACHE_LINE_SIZE_WIDTH - 2; /* 3-bit = 111 */
77
parameter CACHE_TAG_ENTRIES         = 2 ** CACHE_LINE_ADDR_WIDTH ; /* 256 tag entries */
78
parameter CACHE_DSIZE               = CACHE_LINE_ADDR_WIDTH * CACHE_LINE_SIZE_BYTES; /* 8KB data */
79
parameter CACHE_DWIDTH              = CACHE_LINE_ADDR_WIDTH + CACHE_LINE_SIZE_WIDTH - 2; /* 10-bits */
80
 
81
parameter CACHE_TAG_WIDTH           = 16; /* 16-bit tag entry size */
82
parameter CACHE_TAG_LINE_ADDR_WIDTH = CACHE_TAG_WIDTH - 1; /* 15 bits of data (tag entry size minus valid bit) */
83
 
84
parameter CACHE_TAG_ADDR_LOW        = CACHE_LINE_SIZE_WIDTH + CACHE_LINE_ADDR_WIDTH;
85
parameter CACHE_TAG_ADDR_HIGH       = CACHE_TAG_LINE_ADDR_WIDTH + CACHE_LINE_SIZE_WIDTH + CACHE_LINE_ADDR_WIDTH - 1;
86
 
87
// Tag fields
88
parameter CACHE_TAG_VALID_BIT       = 15;
89
 
90
//  31          16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
91
// |--------------|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
92
//  +--------------------+  +-------------------+   +-----------+      
93
//    Tag entry                     Line address         Address 
94
//       (15-bits)                    (8-bits)           within line 
95
//                                                       (5-bits)
96
 
97
//-----------------------------------------------------------------
98
// Registers / Wires
99
//-----------------------------------------------------------------
100 32 ultra_embe
 
101
// Tag read / write data
102 37 ultra_embe
wire [CACHE_TAG_WIDTH-1:0]      tag_out_w;
103
reg  [CACHE_TAG_WIDTH-1:0]      tag_in_r;
104
reg                             tag_wr_r;
105 27 ultra_embe
 
106 32 ultra_embe
// Tag address
107 37 ultra_embe
wire [CACHE_LINE_ADDR_WIDTH-1:0] tag_address_w;
108 32 ultra_embe
 
109
// Data memory read / write
110 37 ultra_embe
wire [CACHE_DWIDTH-1:0]         address_rd_w;
111
wire [CACHE_DWIDTH-1:0]         address_wr_w;
112
wire                            cache_wr_w;
113 27 ultra_embe
 
114 32 ultra_embe
// Current / Miss PC
115 37 ultra_embe
reg [31:0]                      last_pc_q;
116
reg [31:0]                      miss_pc_q;
117 27 ultra_embe
 
118 32 ultra_embe
// Flush state
119 37 ultra_embe
reg                             flush_q;
120
reg [CACHE_LINE_ADDR_WIDTH-1:0] flush_addr_q;
121
reg                             flush_wr_q;
122 27 ultra_embe
 
123 32 ultra_embe
// Other state
124 37 ultra_embe
reg                             read_while_busy_q;
125 27 ultra_embe
 
126
// Current state
127
parameter STATE_CHECK       = 0;
128
parameter STATE_FETCH       = 1;
129
parameter STATE_WAIT        = 2;
130 36 ultra_embe
parameter STATE_FLUSH       = 3;
131 37 ultra_embe
reg [1:0]                   state_q;
132 27 ultra_embe
 
133 32 ultra_embe
// Tag address from input PC or flopped version of it
134 37 ultra_embe
assign tag_address_w      = (state_q != STATE_CHECK) ?
135
                          miss_pc_q[CACHE_LINE_ADDR_WIDTH + CACHE_LINE_SIZE_WIDTH - 1:CACHE_LINE_SIZE_WIDTH] :
136 32 ultra_embe
                          pc_i[CACHE_LINE_ADDR_WIDTH + CACHE_LINE_SIZE_WIDTH - 1:CACHE_LINE_SIZE_WIDTH];
137 27 ultra_embe
 
138 32 ultra_embe
// Cache read address
139 37 ultra_embe
assign address_rd_w   = pc_i[CACHE_LINE_ADDR_WIDTH + CACHE_LINE_SIZE_WIDTH - 1:2];
140 27 ultra_embe
 
141 32 ultra_embe
// Cache miss output if requested PC is not in the tag memory
142 37 ultra_embe
wire miss_w               = ~tag_out_w[CACHE_TAG_VALID_BIT] |
143
                            (last_pc_q[CACHE_TAG_ADDR_HIGH:CACHE_TAG_ADDR_LOW] != tag_out_w[14:0]);
144 32 ultra_embe
 
145 36 ultra_embe
// Stall the CPU if cache state machine is not idle!
146 37 ultra_embe
wire busy_w               = (state_q != STATE_CHECK) | read_while_busy_q;
147 36 ultra_embe
 
148 32 ultra_embe
// Cache output valid
149 37 ultra_embe
assign valid_o            = busy_w ? 1'b0 : ~miss_w;
150 27 ultra_embe
 
151 32 ultra_embe
// Flushing: Last line to flush
152 37 ultra_embe
wire flush_last_w         = (flush_addr_q == {CACHE_LINE_ADDR_WIDTH{1'b0}});
153 32 ultra_embe
 
154
// Is this a cache miss?
155 37 ultra_embe
wire cache_miss_w         = miss_w &                // Tag lookup failed
156
                            !rd_i &                 // NOT new read request cycle
157
                            !read_while_busy_q &    // NOT pending read whilst busy
158
                            !flush_q &              // NOT flush request
159
                            !invalidate_i;
160 32 ultra_embe
 
161 37 ultra_embe
wire        mem_fetch_w = (state_q == STATE_CHECK) & cache_miss_w;
162
wire [31:0] mem_data_w;
163
wire [31:0] mem_resp_addr_w;
164
wire        mem_valid_w;
165
wire        mem_final_w;
166
 
167 27 ultra_embe
//-----------------------------------------------------------------
168 32 ultra_embe
// Next State Logic
169 27 ultra_embe
//-----------------------------------------------------------------
170 37 ultra_embe
reg [1:0] next_state_r;
171 32 ultra_embe
always @ *
172
begin
173 37 ultra_embe
    next_state_r = state_q;
174 27 ultra_embe
 
175 37 ultra_embe
    case (state_q)
176 32 ultra_embe
 
177
    //-----------------------------------------
178
    // CHECK - check cache for hit or miss
179
    //-----------------------------------------
180
    STATE_CHECK :
181
    begin
182
        // Cache flush request pending?
183 37 ultra_embe
        if (flush_q || invalidate_i)
184 32 ultra_embe
            next_state_r    = STATE_FLUSH;
185
        // Cache miss (& new read request not pending)
186 37 ultra_embe
        else if (cache_miss_w)
187 32 ultra_embe
            next_state_r    = STATE_FETCH;
188
        // Cache hit (or new read request)
189
        else
190
            next_state_r    = STATE_CHECK;
191
    end
192
    //-----------------------------------------
193
    // FETCH - Fetch row from memory
194
    //-----------------------------------------
195
    STATE_FETCH :
196
    begin
197
        // Line fetch complete?
198 37 ultra_embe
        if (mem_final_w)
199 32 ultra_embe
           next_state_r = STATE_WAIT;
200
    end
201
    //-----------------------------------------
202
    // FLUSH - Invalidate tag memory
203
    //-----------------------------------------
204
    STATE_FLUSH :
205
    begin
206 37 ultra_embe
        if (flush_last_w)
207
            next_state_r = STATE_CHECK;
208 32 ultra_embe
        else
209
            next_state_r = STATE_FLUSH;
210 36 ultra_embe
    end
211 32 ultra_embe
    //-----------------------------------------
212
    // WAIT - Wait cycle
213
    //-----------------------------------------
214
    STATE_WAIT :
215
        next_state_r = STATE_CHECK;
216
    default:
217
        ;
218
   endcase
219
end
220
 
221
// Update state
222 27 ultra_embe
always @ (posedge rst_i or posedge clk_i )
223
begin
224
   if (rst_i == 1'b1)
225 37 ultra_embe
        state_q   <= STATE_FLUSH;
226 32 ultra_embe
   else
227 37 ultra_embe
        state_q   <= next_state_r;
228 32 ultra_embe
end
229
 
230
//-----------------------------------------------------------------
231 37 ultra_embe
// Flop request details
232 32 ultra_embe
//-----------------------------------------------------------------
233
always @ (posedge rst_i or posedge clk_i )
234
begin
235
   if (rst_i == 1'b1)
236 27 ultra_embe
   begin
237 37 ultra_embe
        miss_pc_q   <= BOOT_VECTOR + `VECTOR_RESET;
238
        last_pc_q   <= 32'h00000000;
239 32 ultra_embe
   end
240
   else
241
   begin
242 37 ultra_embe
        last_pc_q   <= pc_i;
243 27 ultra_embe
 
244 37 ultra_embe
        case (state_q)
245 32 ultra_embe
 
246
        //-----------------------------------------
247
        // CHECK - check cache for hit or miss
248
        //-----------------------------------------
249
        STATE_CHECK :
250
        begin
251 37 ultra_embe
            // Cache hit (or new read request), store fetch PC
252
            if (!cache_miss_w)
253
                miss_pc_q   <= pc_i;
254
        end
255 32 ultra_embe
        default:
256
            ;
257
       endcase
258
   end
259
end
260
 
261
//-----------------------------------------------------------------
262 37 ultra_embe
// Detect new read request whilst busy
263 32 ultra_embe
//-----------------------------------------------------------------
264
always @ (posedge rst_i or posedge clk_i )
265
begin
266
   if (rst_i == 1'b1)
267 37 ultra_embe
   begin
268
        read_while_busy_q <= 1'b0;
269 32 ultra_embe
   end
270
   else
271
   begin
272 37 ultra_embe
        case (state_q)
273 32 ultra_embe
        //-----------------------------------------
274 37 ultra_embe
        // CHECK - Check cache for hit or miss
275 32 ultra_embe
        //-----------------------------------------
276
        STATE_CHECK :
277
        begin
278 37 ultra_embe
            read_while_busy_q <= 1'b0;
279
        end
280 32 ultra_embe
        //-----------------------------------------
281 37 ultra_embe
        // OTHER - Fetching, flushing, waiting
282 32 ultra_embe
        //-----------------------------------------
283 37 ultra_embe
        default:
284 32 ultra_embe
        begin
285 37 ultra_embe
            // New request whilst cache busy?
286
            if (rd_i)
287
                read_while_busy_q <= 1'b1;
288
        end
289
        endcase
290 32 ultra_embe
   end
291
end
292
 
293
//-----------------------------------------------------------------
294 37 ultra_embe
// Cache Tag Write
295 32 ultra_embe
//-----------------------------------------------------------------
296 37 ultra_embe
always @ *
297 32 ultra_embe
begin
298 37 ultra_embe
    tag_in_r    = {CACHE_TAG_WIDTH{1'b0}};
299
    tag_wr_r    = 1'b0;
300 27 ultra_embe
 
301 37 ultra_embe
    case (state_q)
302 27 ultra_embe
 
303 37 ultra_embe
    //-----------------------------------------
304
    // CHECK - check cache for hit or miss
305
    //-----------------------------------------
306
    STATE_CHECK :
307
    begin
308
        // Cache miss (& new read request not pending)
309
        if (cache_miss_w)
310 32 ultra_embe
        begin
311 37 ultra_embe
            // Update tag memory with this line's details
312
            tag_in_r    = {1'b1, miss_pc_q[CACHE_TAG_ADDR_HIGH:CACHE_TAG_ADDR_LOW]};
313
            tag_wr_r    = 1'b1;
314 32 ultra_embe
        end
315 37 ultra_embe
    end
316
    default:
317
        ;
318
   endcase
319 32 ultra_embe
end
320 27 ultra_embe
 
321 32 ultra_embe
//-----------------------------------------------------------------
322 37 ultra_embe
// Flush Logic
323 32 ultra_embe
//-----------------------------------------------------------------
324 37 ultra_embe
reg                             flush_r;
325
reg [CACHE_LINE_ADDR_WIDTH-1:0] flush_addr_r;
326
reg                             flush_wr_r;
327 27 ultra_embe
 
328 37 ultra_embe
always @ *
329 32 ultra_embe
begin
330 37 ultra_embe
    flush_wr_r   = 1'b0;
331
    flush_addr_r = flush_addr_q;
332
    flush_r      = flush_q;
333
 
334
    case (state_q)
335 32 ultra_embe
 
336 37 ultra_embe
    //-----------------------------------------
337
    // CHECK - Check cache for hit or miss
338
    //-----------------------------------------
339
    STATE_CHECK :
340
    begin
341
        // Cache flush request pending?
342
        if (flush_q || invalidate_i)
343 32 ultra_embe
        begin
344 37 ultra_embe
            flush_r         = 1'b0;
345
            flush_addr_r    = {CACHE_LINE_ADDR_WIDTH{1'b1}};
346
            flush_wr_r      = 1'b1;
347 32 ultra_embe
        end
348 37 ultra_embe
    end
349
    //-----------------------------------------
350
    // FLUSH - Invalidate tag memory
351
    //-----------------------------------------
352
    STATE_FLUSH :
353
    begin
354
        flush_addr_r  = flush_addr_q - 1;
355
        flush_wr_r    = 1'b1;
356
    end
357
    //-----------------------------------------
358
    // OTHER - Fetching / wait cycles
359
    //-----------------------------------------
360
    default:
361
    begin
362
        // Latch invalidate request even if can't be actioned now...
363
        if (invalidate_i)
364
            flush_r     = 1'b1;
365
    end
366
    endcase
367 27 ultra_embe
end
368
 
369 32 ultra_embe
always @ (posedge rst_i or posedge clk_i )
370
begin
371
   if (rst_i == 1'b1)
372 37 ultra_embe
   begin
373
        flush_addr_q    <= {CACHE_LINE_ADDR_WIDTH{1'b1}};
374
        flush_wr_q      <= 1'b0;
375
        flush_q         <= 1'b0;
376
   end
377 32 ultra_embe
   else
378
   begin
379 37 ultra_embe
        flush_addr_q    <= flush_addr_r;
380
        flush_wr_q      <= flush_wr_r;
381
        flush_q         <= flush_r;
382 32 ultra_embe
   end
383
end
384
 
385 27 ultra_embe
//-----------------------------------------------------------------
386 37 ultra_embe
// External Mem Access
387 27 ultra_embe
//-----------------------------------------------------------------
388 37 ultra_embe
altor32_wb_fetch
389
u_wb
390
(
391
    .clk_i(clk_i),
392
    .rst_i(rst_i),
393 32 ultra_embe
 
394 37 ultra_embe
    // Request
395
    .fetch_i(mem_fetch_w),
396
    .burst_i(1'b1),
397
    .address_i(miss_pc_q),
398 32 ultra_embe
 
399 37 ultra_embe
    // Response
400
    .resp_addr_o(mem_resp_addr_w),
401
    .data_o(mem_data_w),
402
    .valid_o(mem_valid_w),
403
    .final_o(mem_final_w),
404
 
405
    // Wishbone interface
406
    .wbm_addr_o(wbm_addr_o),
407
    .wbm_dat_i(wbm_dat_i),
408
    .wbm_cti_o(wbm_cti_o),
409
    .wbm_cyc_o(wbm_cyc_o),
410
    .wbm_stb_o(wbm_stb_o),
411
    .wbm_stall_i(wbm_stall_i),
412
    .wbm_ack_i(wbm_ack_i)
413
);
414
 
415 32 ultra_embe
//-----------------------------------------------------------------
416
// Tag memory
417
//-----------------------------------------------------------------
418 27 ultra_embe
altor32_ram_dp
419
#(
420
    .WIDTH(CACHE_TAG_WIDTH),
421
    .SIZE(CACHE_LINE_ADDR_WIDTH)
422
)
423
u1_tag_mem
424
(
425 32 ultra_embe
    // Tag read/write port
426 27 ultra_embe
    .aclk_i(clk_i),
427 37 ultra_embe
    .adat_o(tag_out_w),
428
    .adat_i(tag_in_r),
429
    .aadr_i(tag_address_w),
430
    .awr_i(tag_wr_r),
431 27 ultra_embe
 
432 32 ultra_embe
    // Tag invalidate port
433 27 ultra_embe
    .bclk_i(clk_i),
434 37 ultra_embe
    .badr_i(flush_addr_q),
435 27 ultra_embe
    .bdat_o(/*open*/),
436
    .bdat_i({CACHE_TAG_WIDTH{1'b0}}),
437 37 ultra_embe
    .bwr_i(flush_wr_q)
438 27 ultra_embe
);
439 32 ultra_embe
 
440
//-----------------------------------------------------------------
441 27 ultra_embe
// Data memory
442 32 ultra_embe
//-----------------------------------------------------------------
443 27 ultra_embe
altor32_ram_dp
444
#(
445
    .WIDTH(32),
446
    .SIZE(CACHE_DWIDTH)
447
)
448
u2_data_mem
449
(
450 32 ultra_embe
    // Data read port
451 27 ultra_embe
    .aclk_i(clk_i),
452 37 ultra_embe
    .aadr_i(address_rd_w),
453 27 ultra_embe
    .adat_o(instruction_o),
454
    .adat_i(32'h00),
455
    .awr_i(1'b0),
456
 
457 32 ultra_embe
    // Data write port
458 27 ultra_embe
    .bclk_i(clk_i),
459 37 ultra_embe
    .badr_i(address_wr_w),
460 27 ultra_embe
    .bdat_o(/*open*/),
461 37 ultra_embe
    .bdat_i(mem_data_w),
462
    .bwr_i(cache_wr_w)
463 27 ultra_embe
);
464
 
465 36 ultra_embe
// Write to cache on wishbone response
466 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]};
467 36 ultra_embe
 
468 37 ultra_embe
assign cache_wr_w = (state_q == STATE_FETCH) & mem_valid_w;
469 36 ultra_embe
 
470 27 ultra_embe
endmodule
471
 

powered by: WebSVN 2.1.0

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