OpenCores
URL https://opencores.org/ocsvn/an-fpga-implementation-of-low-latency-noc-based-mpsoc/an-fpga-implementation-of-low-latency-noc-based-mpsoc/trunk

Subversion Repositories an-fpga-implementation-of-low-latency-noc-based-mpsoc

[/] [an-fpga-implementation-of-low-latency-noc-based-mpsoc/] [trunk/] [mpsoc/] [src_processor/] [new_lm32/] [rtl/] [lm32_icache.v] - Blame information for rev 48

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 48 alirezamon
//   ==================================================================
2
//   >>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
3
//   ------------------------------------------------------------------
4
//   Copyright (c) 2006-2011 by Lattice Semiconductor Corporation
5
//   ALL RIGHTS RESERVED
6
//   ------------------------------------------------------------------
7
//
8
//   IMPORTANT: THIS FILE IS AUTO-GENERATED BY THE LATTICEMICO SYSTEM.
9
//
10
//   Permission:
11
//
12
//      Lattice Semiconductor grants permission to use this code
13
//      pursuant to the terms of the Lattice Semiconductor Corporation
14
//      Open Source License Agreement.
15
//
16
//   Disclaimer:
17
//
18
//      Lattice Semiconductor provides no warranty regarding the use or
19
//      functionality of this code. It is the user's responsibility to
20
//      verify the user's design for consistency and functionality through
21
//      the use of formal verification methods.
22
//
23
//   --------------------------------------------------------------------
24
//
25
//                  Lattice Semiconductor Corporation
26
//                  5555 NE Moore Court
27
//                  Hillsboro, OR 97214
28
//                  U.S.A
29
//
30
//                  TEL: 1-800-Lattice (USA and Canada)
31
//                         503-286-8001 (other locations)
32
//
33
//                  web: http://www.latticesemi.com/
34
//                  email: techsupport@latticesemi.com
35
//
36
//   --------------------------------------------------------------------
37
//                         FILE DETAILS
38
// Project          : LatticeMico32
39
// File             : lm32_icache.v
40
// Title            : Instruction cache
41
// Dependencies     : lm32_include.v
42
//
43
// Version 3.5
44
// 1. Bug Fix: Instruction cache flushes issued from Instruction Inline Memory
45
//    cause segmentation fault due to incorrect fetches.
46
//
47
// Version 3.1
48
// 1. Feature: Support for user-selected resource usage when implementing
49
//    cache memory. Additional parameters must be defined when invoking module
50
//    lm32_ram. Instruction cache miss mechanism is dependent on branch
51
//    prediction being performed in D stage of pipeline.
52
//
53
// Version 7.0SP2, 3.0
54
// No change
55
// =============================================================================
56
 
57
`include "lm32_include.v"
58
 
59
`ifdef CFG_ICACHE_ENABLED
60
 
61
`define LM32_IC_ADDR_OFFSET_RNG          addr_offset_msb:addr_offset_lsb
62
`define LM32_IC_ADDR_SET_RNG             addr_set_msb:addr_set_lsb
63
`define LM32_IC_ADDR_TAG_RNG             addr_tag_msb:addr_tag_lsb
64
`define LM32_IC_ADDR_IDX_RNG             addr_set_msb:addr_offset_lsb
65
 
66
`define LM32_IC_TMEM_ADDR_WIDTH          addr_set_width
67
`define LM32_IC_TMEM_ADDR_RNG            (`LM32_IC_TMEM_ADDR_WIDTH-1):0
68
`define LM32_IC_DMEM_ADDR_WIDTH          (addr_offset_width+addr_set_width)
69
`define LM32_IC_DMEM_ADDR_RNG            (`LM32_IC_DMEM_ADDR_WIDTH-1):0
70
 
71
`define LM32_IC_TAGS_WIDTH               (addr_tag_width+1)
72
`define LM32_IC_TAGS_RNG                 (`LM32_IC_TAGS_WIDTH-1):0
73
`define LM32_IC_TAGS_TAG_RNG             (`LM32_IC_TAGS_WIDTH-1):1
74
`define LM32_IC_TAGS_VALID_RNG           0
75
 
76
`define LM32_IC_STATE_RNG                3:0
77
`define LM32_IC_STATE_FLUSH_INIT         4'b0001
78
`define LM32_IC_STATE_FLUSH              4'b0010
79
`define LM32_IC_STATE_CHECK              4'b0100
80
`define LM32_IC_STATE_REFILL             4'b1000
81
 
82
/////////////////////////////////////////////////////
83
// Module interface
84
/////////////////////////////////////////////////////
85
 
86
module lm32_icache (
87
    // ----- Inputs -----
88
    clk_i,
89
    rst_i,
90
    stall_a,
91
    stall_f,
92
    address_a,
93
    address_f,
94
`ifdef CFG_MMU_ENABLED
95
    physical_address_f,
96
`endif
97
    read_enable_f,
98
    refill_ready,
99
    refill_data,
100
    iflush,
101
`ifdef CFG_IROM_ENABLED
102
    select_f,
103
`endif
104
    valid_d,
105
    branch_predict_taken_d,
106
    // ----- Outputs -----
107
    stall_request,
108
    restart_request,
109
    refill_request,
110
    refill_address,
111
`ifdef CFG_MMU_ENABLED
112
    physical_refill_address,
113
`endif
114
    refilling,
115
    inst
116
    );
117
 
118
/////////////////////////////////////////////////////
119
// Parameters
120
/////////////////////////////////////////////////////
121
 
122
parameter associativity = 1;                            // Associativity of the cache (Number of ways)
123
parameter sets = 512;                                   // Number of sets
124
parameter bytes_per_line = 16;                          // Number of bytes per cache line
125
parameter base_address = 0;                             // Base address of cachable memory
126
parameter limit = 0;                                    // Limit (highest address) of cachable memory
127
 
128
localparam addr_offset_width = `CLOG2(bytes_per_line)-2;
129
localparam addr_set_width = `CLOG2(sets);
130
localparam addr_offset_lsb = 2;
131
localparam addr_offset_msb = (addr_offset_lsb+addr_offset_width-1);
132
localparam addr_set_lsb = (addr_offset_msb+1);
133
localparam addr_set_msb = (addr_set_lsb+addr_set_width-1);
134
`ifdef CFG_MMU_ENABLED
135
localparam addr_tag_lsb = (addr_offset_msb+1);
136
`else
137
localparam addr_tag_lsb = (addr_set_msb+1);
138
`endif
139
localparam addr_tag_msb = `CLOG2(`CFG_ICACHE_LIMIT-`CFG_ICACHE_BASE_ADDRESS);
140
localparam addr_tag_width = (addr_tag_msb-addr_tag_lsb+1);
141
 
142
/////////////////////////////////////////////////////
143
// Inputs
144
/////////////////////////////////////////////////////
145
 
146
input clk_i;                                        // Clock
147
input rst_i;                                        // Reset
148
 
149
input stall_a;                                      // Stall instruction in A stage
150
input stall_f;                                      // Stall instruction in F stage
151
 
152
input valid_d;                                      // Valid instruction in D stage
153
input branch_predict_taken_d;                       // Instruction in D stage is a branch and is predicted taken
154
 
155
input [`LM32_PC_RNG] address_a;                     // Address of instruction in A stage
156
input [`LM32_PC_RNG] address_f;                     // Address of instruction in F stage
157
`ifdef CFG_MMU_ENABLED
158
input [`LM32_PC_RNG] physical_address_f;            // Physical address of instruction in F stage
159
`endif
160
input read_enable_f;                                // Indicates if cache access is valid
161
 
162
input refill_ready;                                 // Next word of refill data is ready
163
input [`LM32_INSTRUCTION_RNG] refill_data;          // Data to refill the cache with
164
 
165
input iflush;                                       // Flush the cache
166
`ifdef CFG_IROM_ENABLED
167
input select_f;                                     // Instruction in F stage is mapped through instruction cache
168
`endif
169
 
170
/////////////////////////////////////////////////////
171
// Outputs
172
/////////////////////////////////////////////////////
173
 
174
output stall_request;                               // Request to stall the pipeline
175
wire   stall_request;
176
output restart_request;                             // Request to restart instruction that caused the cache miss
177
reg    restart_request;
178
output refill_request;                              // Request to refill a cache line
179
wire   refill_request;
180
output [`LM32_PC_RNG] refill_address;               // Base address of cache refill
181
reg    [`LM32_PC_RNG] refill_address;
182
`ifdef CFG_MMU_ENABLED
183
output [`LM32_PC_RNG] physical_refill_address;      // Physical base address of cache refill
184
reg    [`LM32_PC_RNG] physical_refill_address;
185
`endif
186
output refilling;                                   // Indicates the instruction cache is currently refilling
187
reg    refilling;
188
output [`LM32_INSTRUCTION_RNG] inst;                // Instruction read from cache
189
wire   [`LM32_INSTRUCTION_RNG] inst;
190
 
191
/////////////////////////////////////////////////////
192
// Internal nets and registers
193
/////////////////////////////////////////////////////
194
 
195
wire enable;
196
wire [0:associativity-1] way_mem_we;
197
wire [`LM32_INSTRUCTION_RNG] way_data[0:associativity-1];
198
wire [`LM32_IC_TAGS_TAG_RNG] way_tag[0:associativity-1];
199
wire [0:associativity-1] way_valid;
200
wire [0:associativity-1] way_match;
201
wire miss;
202
 
203
wire [`LM32_IC_TMEM_ADDR_RNG] tmem_read_address;
204
wire [`LM32_IC_TMEM_ADDR_RNG] tmem_write_address;
205
wire [`LM32_IC_DMEM_ADDR_RNG] dmem_read_address;
206
wire [`LM32_IC_DMEM_ADDR_RNG] dmem_write_address;
207
wire [`LM32_IC_TAGS_RNG] tmem_write_data;
208
 
209
reg [`LM32_IC_STATE_RNG] state;
210
wire flushing;
211
wire check;
212
wire refill;
213
 
214
reg [associativity-1:0] refill_way_select;
215
reg [`LM32_IC_ADDR_OFFSET_RNG] refill_offset;
216
wire last_refill;
217
reg [`LM32_IC_TMEM_ADDR_RNG] flush_set;
218
 
219
genvar i;
220
 
221
/////////////////////////////////////////////////////
222
// Functions
223
/////////////////////////////////////////////////////
224
 
225
/////////////////////////////////////////////////////
226
// Instantiations
227
/////////////////////////////////////////////////////
228
 
229
   generate
230
      for (i = 0; i < associativity; i = i + 1)
231
        begin : memories
232
 
233
           lm32_ram
234
             #(
235
               // ----- Parameters -------
236
               .data_width                 (32),
237
               .address_width              (`LM32_IC_DMEM_ADDR_WIDTH)
238
// Modified for Milkymist: removed non-portable RAM parameters
239
)
240
           way_0_data_ram
241
             (
242
              // ----- Inputs -------
243
              .read_clk                   (clk_i),
244
              .write_clk                  (clk_i),
245
              .reset                      (rst_i),
246
              .read_address               (dmem_read_address),
247
              .enable_read                (enable),
248
              .write_address              (dmem_write_address),
249
              .enable_write               (`TRUE),
250
              .write_enable               (way_mem_we[i]),
251
              .write_data                 (refill_data),
252
              // ----- Outputs -------
253
              .read_data                  (way_data[i])
254
              );
255
 
256
           lm32_ram
257
             #(
258
               // ----- Parameters -------
259
               .data_width                 (`LM32_IC_TAGS_WIDTH),
260
               .address_width              (`LM32_IC_TMEM_ADDR_WIDTH)
261
// Modified for Milkymist: removed non-portable RAM parameters
262
               )
263
           way_0_tag_ram
264
             (
265
              // ----- Inputs -------
266
              .read_clk                   (clk_i),
267
              .write_clk                  (clk_i),
268
              .reset                      (rst_i),
269
              .read_address               (tmem_read_address),
270
              .enable_read                (enable),
271
              .write_address              (tmem_write_address),
272
              .enable_write               (`TRUE),
273
              .write_enable               (way_mem_we[i] | flushing),
274
              .write_data                 (tmem_write_data),
275
              // ----- Outputs -------
276
              .read_data                  ({way_tag[i], way_valid[i]})
277
              );
278
 
279
        end
280
endgenerate
281
 
282
/////////////////////////////////////////////////////
283
// Combinational logic
284
/////////////////////////////////////////////////////
285
 
286
// Compute which ways in the cache match the address address being read
287
generate
288
    for (i = 0; i < associativity; i = i + 1)
289
    begin : match
290
assign way_match[i] =
291
`ifdef CFG_MMU_ENABLED
292
        ({way_tag[i], way_valid[i]} == {physical_address_f[`LM32_IC_ADDR_TAG_RNG], `TRUE});
293
`else
294
        ({way_tag[i], way_valid[i]} == {address_f[`LM32_IC_ADDR_TAG_RNG], `TRUE});
295
`endif
296
    end
297
endgenerate
298
 
299
// Select data from way that matched the address being read
300
generate
301
    if (associativity == 1)
302
    begin : inst_1
303
assign inst = way_match[0] ? way_data[0] : 32'b0;
304
    end
305
    else if (associativity == 2)
306
         begin : inst_2
307
assign inst = way_match[0] ? way_data[0] : (way_match[1] ? way_data[1] : 32'b0);
308
    end
309
endgenerate
310
 
311
// Compute address to use to index into the data memories
312
generate
313
    if (bytes_per_line > 4)
314
assign dmem_write_address = {refill_address[`LM32_IC_ADDR_SET_RNG], refill_offset};
315
    else
316
assign dmem_write_address = refill_address[`LM32_IC_ADDR_SET_RNG];
317
endgenerate
318
 
319
assign dmem_read_address = address_a[`LM32_IC_ADDR_IDX_RNG];
320
 
321
// Compute address to use to index into the tag memories
322
assign tmem_read_address = address_a[`LM32_IC_ADDR_SET_RNG];
323
assign tmem_write_address = flushing
324
                                ? flush_set
325
                                : refill_address[`LM32_IC_ADDR_SET_RNG];
326
 
327
// Compute signal to indicate when we are on the last refill accesses
328
generate
329
    if (bytes_per_line > 4)
330
assign last_refill = refill_offset == {addr_offset_width{1'b1}};
331
    else
332
assign last_refill = `TRUE;
333
endgenerate
334
 
335
// Compute data and tag memory access enable
336
assign enable = (stall_a == `FALSE);
337
 
338
// Compute data and tag memory write enables
339
generate
340
    if (associativity == 1)
341
    begin : we_1
342
assign way_mem_we[0] = (refill_ready == `TRUE);
343
    end
344
    else
345
    begin : we_2
346
assign way_mem_we[0] = (refill_ready == `TRUE) && (refill_way_select[0] == `TRUE);
347
assign way_mem_we[1] = (refill_ready == `TRUE) && (refill_way_select[1] == `TRUE);
348
    end
349
endgenerate
350
 
351
// On the last refill cycle set the valid bit, for all other writes it should be cleared
352
assign tmem_write_data[`LM32_IC_TAGS_VALID_RNG] = last_refill & !flushing;
353
assign tmem_write_data[`LM32_IC_TAGS_TAG_RNG] =
354
`ifdef CFG_MMU_ENABLED
355
       physical_refill_address[`LM32_IC_ADDR_TAG_RNG];
356
`else
357
       refill_address[`LM32_IC_ADDR_TAG_RNG];
358
`endif
359
 
360
// Signals that indicate which state we are in
361
assign flushing = |state[1:0];
362
assign check = state[2];
363
assign refill = state[3];
364
 
365
assign miss = (~(|way_match)) && (read_enable_f == `TRUE) && (stall_f == `FALSE) && !(valid_d && branch_predict_taken_d);
366
assign stall_request = (check == `FALSE);
367
assign refill_request = (refill == `TRUE);
368
 
369
/////////////////////////////////////////////////////
370
// Sequential logic
371
/////////////////////////////////////////////////////
372
 
373
// Record way selected for replacement on a cache miss
374
generate
375
    if (associativity >= 2)
376
    begin : way_select
377
always @(posedge clk_i `CFG_RESET_SENSITIVITY)
378
begin
379
    if (rst_i == `TRUE)
380
        refill_way_select <= {{associativity-1{1'b0}}, 1'b1};
381
    else
382
    begin
383
        if (miss == `TRUE)
384
            refill_way_select <= {refill_way_select[0], refill_way_select[1]};
385
    end
386
end
387
    end
388
endgenerate
389
 
390
// Record whether we are refilling
391
always @(posedge clk_i `CFG_RESET_SENSITIVITY)
392
begin
393
    if (rst_i == `TRUE)
394
        refilling <= `FALSE;
395
    else
396
        refilling <= refill;
397
end
398
 
399
// Instruction cache control FSM
400
always @(posedge clk_i `CFG_RESET_SENSITIVITY)
401
begin
402
    if (rst_i == `TRUE)
403
    begin
404
        state <= `LM32_IC_STATE_FLUSH_INIT;
405
        flush_set <= {`LM32_IC_TMEM_ADDR_WIDTH{1'b1}};
406
        refill_address <= {`LM32_PC_WIDTH{1'bx}};
407
`ifdef CFG_MMU_ENABLED
408
        physical_refill_address <= {`LM32_PC_WIDTH{1'bx}};
409
`endif
410
        restart_request <= `FALSE;
411
    end
412
    else
413
    begin
414
        case (state)
415
 
416
        // Flush the cache for the first time after reset
417
        `LM32_IC_STATE_FLUSH_INIT:
418
        begin
419
            if (flush_set == {`LM32_IC_TMEM_ADDR_WIDTH{1'b0}})
420
                state <= `LM32_IC_STATE_CHECK;
421
            flush_set <= flush_set - 1'b1;
422
        end
423
 
424
        // Flush the cache in response to an write to the ICC CSR
425
        `LM32_IC_STATE_FLUSH:
426
        begin
427
            if (flush_set == {`LM32_IC_TMEM_ADDR_WIDTH{1'b0}})
428
`ifdef CFG_IROM_ENABLED
429
              if (select_f)
430
                state <= `LM32_IC_STATE_REFILL;
431
              else
432
`endif
433
                state <= `LM32_IC_STATE_CHECK;
434
 
435
            flush_set <= flush_set - 1'b1;
436
        end
437
 
438
        // Check for cache misses
439
        `LM32_IC_STATE_CHECK:
440
        begin
441
            if (stall_a == `FALSE)
442
                restart_request <= `FALSE;
443
            if (iflush == `TRUE)
444
            begin
445
`ifdef CFG_MMU_ENABLED
446
                physical_refill_address <= physical_address_f;
447
                refill_address <= address_f;
448
`else
449
                refill_address <= address_f;
450
`endif
451
                state <= `LM32_IC_STATE_FLUSH;
452
            end
453
            else if (miss == `TRUE)
454
            begin
455
`ifdef CFG_MMU_ENABLED
456
                physical_refill_address <= physical_address_f;
457
                refill_address <= address_f;
458
`else
459
                refill_address <= address_f;
460
`endif
461
                state <= `LM32_IC_STATE_REFILL;
462
            end
463
        end
464
 
465
        // Refill a cache line
466
        `LM32_IC_STATE_REFILL:
467
        begin
468
            if (refill_ready == `TRUE)
469
            begin
470
                if (last_refill == `TRUE)
471
                begin
472
                    restart_request <= `TRUE;
473
                    state <= `LM32_IC_STATE_CHECK;
474
                end
475
            end
476
        end
477
 
478
        endcase
479
    end
480
end
481
 
482
generate
483
    if (bytes_per_line > 4)
484
    begin
485
// Refill offset
486
always @(posedge clk_i `CFG_RESET_SENSITIVITY)
487
begin
488
    if (rst_i == `TRUE)
489
        refill_offset <= {addr_offset_width{1'b0}};
490
    else
491
    begin
492
        case (state)
493
 
494
        // Check for cache misses
495
        `LM32_IC_STATE_CHECK:
496
        begin
497
            if (iflush == `TRUE)
498
                refill_offset <= {addr_offset_width{1'b0}};
499
            else if (miss == `TRUE)
500
                refill_offset <= {addr_offset_width{1'b0}};
501
        end
502
 
503
        // Refill a cache line
504
        `LM32_IC_STATE_REFILL:
505
        begin
506
            if (refill_ready == `TRUE)
507
                refill_offset <= refill_offset + 1'b1;
508
        end
509
 
510
        endcase
511
    end
512
end
513
    end
514
endgenerate
515
 
516
endmodule
517
 
518
`endif
519
 

powered by: WebSVN 2.1.0

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