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_dcache.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_dcache.v
40
// Title            : Data cache
41
// Dependencies     : lm32_include.v
42
// Version          : 6.1.17
43
//                  : Initial Release
44
// Version          : 7.0SP2, 3.0
45
//                  : No Change
46
// Version          : 3.1
47
//                  : Support for user-selected resource usage when implementing
48
//                  : cache memory. Additional parameters must be defined when
49
//                  : invoking lm32_ram.v
50
// =============================================================================
51
 
52
`include "lm32_include.v"
53
 
54
`ifdef CFG_DCACHE_ENABLED
55
 
56
`define LM32_DC_ADDR_OFFSET_RNG          addr_offset_msb:addr_offset_lsb
57
`define LM32_DC_ADDR_SET_RNG             addr_set_msb:addr_set_lsb
58
`define LM32_DC_ADDR_TAG_RNG             addr_tag_msb:addr_tag_lsb
59
`define LM32_DC_ADDR_IDX_RNG             addr_set_msb:addr_offset_lsb
60
 
61
`define LM32_DC_TMEM_ADDR_WIDTH          addr_set_width
62
`define LM32_DC_TMEM_ADDR_RNG            (`LM32_DC_TMEM_ADDR_WIDTH-1):0
63
`define LM32_DC_DMEM_ADDR_WIDTH          (addr_offset_width+addr_set_width)
64
`define LM32_DC_DMEM_ADDR_RNG            (`LM32_DC_DMEM_ADDR_WIDTH-1):0
65
 
66
`define LM32_DC_TAGS_WIDTH               (addr_tag_width+1)
67
`define LM32_DC_TAGS_RNG                 (`LM32_DC_TAGS_WIDTH-1):0
68
`define LM32_DC_TAGS_TAG_RNG             (`LM32_DC_TAGS_WIDTH-1):1
69
`define LM32_DC_TAGS_VALID_RNG           0
70
 
71
`define LM32_DC_STATE_RNG                2:0
72
`define LM32_DC_STATE_FLUSH              3'b001
73
`define LM32_DC_STATE_CHECK              3'b010
74
`define LM32_DC_STATE_REFILL             3'b100
75
 
76
/////////////////////////////////////////////////////
77
// Module interface
78
/////////////////////////////////////////////////////
79
 
80
module lm32_dcache (
81
    // ----- Inputs -----
82
    clk_i,
83
    rst_i,
84
    stall_a,
85
    stall_x,
86
    stall_m,
87
    address_x,
88
    address_m,
89
    load_q_m,
90
    store_q_m,
91
    store_data,
92
    store_byte_select,
93
    refill_ready,
94
    refill_data,
95
    dflush,
96
`ifdef CFG_MMU_ENABLED
97
    dtlb_miss_x,
98
`endif
99
    // ----- Outputs -----
100
    stall_request,
101
    restart_request,
102
    refill_request,
103
    refill_address,
104
    refilling,
105
    load_data
106
    );
107
 
108
/////////////////////////////////////////////////////
109
// Parameters
110
/////////////////////////////////////////////////////
111
 
112
parameter associativity = 1;                            // Associativity of the cache (Number of ways)
113
parameter sets = 512;                                   // Number of sets
114
parameter bytes_per_line = 16;                          // Number of bytes per cache line
115
parameter base_address = 0;                             // Base address of cachable memory
116
parameter limit = 0;                                    // Limit (highest address) of cachable memory
117
 
118
localparam addr_offset_width = `CLOG2(bytes_per_line)-2;
119
localparam addr_set_width = `CLOG2(sets);
120
localparam addr_offset_lsb = 2;
121
localparam addr_offset_msb = (addr_offset_lsb+addr_offset_width-1);
122
localparam addr_set_lsb = (addr_offset_msb+1);
123
localparam addr_set_msb = (addr_set_lsb+addr_set_width-1);
124
`ifdef CFG_MMU_ENABLED
125
localparam addr_tag_lsb = (addr_offset_msb+1);
126
`else
127
localparam addr_tag_lsb = (addr_set_msb+1);
128
`endif
129
localparam addr_tag_msb = `CLOG2(`CFG_DCACHE_LIMIT-`CFG_DCACHE_BASE_ADDRESS);
130
localparam addr_tag_width = (addr_tag_msb-addr_tag_lsb+1);
131
 
132
/////////////////////////////////////////////////////
133
// Inputs
134
/////////////////////////////////////////////////////
135
 
136
input clk_i;                                            // Clock
137
input rst_i;                                            // Reset
138
 
139
input stall_a;                                          // Stall A stage
140
input stall_x;                                          // Stall X stage
141
input stall_m;                                          // Stall M stage
142
 
143
input [`LM32_WORD_RNG] address_x;                       // X stage load/store address
144
input [`LM32_WORD_RNG] address_m;                       // M stage load/store address
145
input load_q_m;                                         // Load instruction in M stage
146
input store_q_m;                                        // Store instruction in M stage
147
input [`LM32_WORD_RNG] store_data;                      // Data to store
148
input [`LM32_BYTE_SELECT_RNG] store_byte_select;        // Which bytes in store data should be modified
149
 
150
input refill_ready;                                     // Indicates next word of refill data is ready
151
input [`LM32_WORD_RNG] refill_data;                     // Refill data
152
 
153
input dflush;                                           // Indicates cache should be flushed
154
 
155
`ifdef CFG_MMU_ENABLED
156
input dtlb_miss_x;                                      // Indicates if a DTLB miss has occured
157
`endif
158
 
159
/////////////////////////////////////////////////////
160
// Outputs
161
/////////////////////////////////////////////////////
162
 
163
output stall_request;                                   // Request pipeline be stalled because cache is busy
164
wire   stall_request;
165
output restart_request;                                 // Request to restart instruction that caused the cache miss
166
reg    restart_request;
167
output refill_request;                                  // Request a refill
168
reg    refill_request;
169
output [`LM32_WORD_RNG] refill_address;                 // Address to refill from
170
reg    [`LM32_WORD_RNG] refill_address;
171
output refilling;                                       // Indicates if the cache is currently refilling
172
reg    refilling;
173
output [`LM32_WORD_RNG] load_data;                      // Data read from cache
174
wire   [`LM32_WORD_RNG] load_data;
175
 
176
/////////////////////////////////////////////////////
177
// Internal nets and registers
178
/////////////////////////////////////////////////////
179
 
180
wire read_port_enable;                                  // Cache memory read port clock enable
181
wire write_port_enable;                                 // Cache memory write port clock enable
182
wire [0:associativity-1] way_tmem_we;                   // Tag memory write enable
183
wire [0:associativity-1] way_dmem_we;                   // Data memory write enable
184
wire [`LM32_WORD_RNG] way_data[0:associativity-1];      // Data read from data memory
185
wire [`LM32_DC_TAGS_TAG_RNG] way_tag[0:associativity-1];// Tag read from tag memory
186
wire [0:associativity-1] way_valid;                     // Indicates which ways are valid
187
wire [0:associativity-1] way_match;                     // Indicates which ways matched
188
wire miss;                                              // Indicates no ways matched
189
 
190
wire [`LM32_DC_TMEM_ADDR_RNG] tmem_read_address;        // Tag memory read address
191
wire [`LM32_DC_TMEM_ADDR_RNG] tmem_write_address;       // Tag memory write address
192
wire [`LM32_DC_DMEM_ADDR_RNG] dmem_read_address;        // Data memory read address
193
wire [`LM32_DC_DMEM_ADDR_RNG] dmem_write_address;       // Data memory write address
194
wire [`LM32_DC_TAGS_RNG] tmem_write_data;               // Tag memory write data
195
reg [`LM32_WORD_RNG] dmem_write_data;                   // Data memory write data
196
 
197
reg [`LM32_DC_STATE_RNG] state;                         // Current state of FSM
198
wire flushing;                                          // Indicates if cache is currently flushing
199
wire check;                                             // Indicates if cache is currently checking for hits/misses
200
wire refill;                                            // Indicates if cache is currently refilling
201
 
202
wire valid_store;                                       // Indicates if there is a valid store instruction
203
reg [associativity-1:0] refill_way_select;              // Which way should be refilled
204
reg [`LM32_DC_ADDR_OFFSET_RNG] refill_offset;           // Which word in cache line should be refilled
205
wire last_refill;                                       // Indicates when on last cycle of cache refill
206
reg [`LM32_DC_TMEM_ADDR_RNG] flush_set;                 // Which set is currently being flushed
207
 
208
genvar i, j;
209
 
210
/////////////////////////////////////////////////////
211
// Functions
212
/////////////////////////////////////////////////////
213
 
214
/////////////////////////////////////////////////////
215
// Instantiations
216
/////////////////////////////////////////////////////
217
 
218
   generate
219
      for (i = 0; i < associativity; i = i + 1)
220
        begin : memories
221
           // Way data
222
           if (`LM32_DC_DMEM_ADDR_WIDTH < 11)
223
             begin : data_memories
224
                lm32_ram
225
                  #(
226
                    // ----- Parameters -------
227
                    .data_width (32),
228
                    .address_width (`LM32_DC_DMEM_ADDR_WIDTH)
229
// Modified for Milkymist: removed non-portable RAM parameters
230
                    ) way_0_data_ram
231
                    (
232
                     // ----- Inputs -------
233
                     .read_clk (clk_i),
234
                     .write_clk (clk_i),
235
                     .reset (rst_i),
236
                     .read_address (dmem_read_address),
237
                     .enable_read (read_port_enable),
238
                     .write_address (dmem_write_address),
239
                     .enable_write (write_port_enable),
240
                     .write_enable (way_dmem_we[i]),
241
                     .write_data (dmem_write_data),
242
                     // ----- Outputs -------
243
                     .read_data (way_data[i])
244
                     );
245
             end
246
           else
247
             begin
248
                for (j = 0; j < 4; j = j + 1)
249
                  begin : byte_memories
250
                     lm32_ram
251
                       #(
252
                         // ----- Parameters -------
253
                         .data_width (8),
254
                         .address_width (`LM32_DC_DMEM_ADDR_WIDTH)
255
// Modified for Milkymist: removed non-portable RAM parameters
256
                         ) way_0_data_ram
257
                         (
258
                          // ----- Inputs -------
259
                          .read_clk (clk_i),
260
                          .write_clk (clk_i),
261
                          .reset (rst_i),
262
                          .read_address (dmem_read_address),
263
                          .enable_read (read_port_enable),
264
                          .write_address (dmem_write_address),
265
                          .enable_write (write_port_enable),
266
                          .write_enable (way_dmem_we[i] & (store_byte_select[j] | refill)),
267
                          .write_data (dmem_write_data[(j+1)*8-1:j*8]),
268
                          // ----- Outputs -------
269
                          .read_data (way_data[i][(j+1)*8-1:j*8])
270
                          );
271
                  end
272
             end
273
 
274
           // Way tags
275
           lm32_ram
276
             #(
277
               // ----- Parameters -------
278
               .data_width (`LM32_DC_TAGS_WIDTH),
279
               .address_width (`LM32_DC_TMEM_ADDR_WIDTH)
280
// Modified for Milkymist: removed non-portable RAM parameters
281
               ) way_0_tag_ram
282
               (
283
                // ----- Inputs -------
284
                .read_clk (clk_i),
285
                .write_clk (clk_i),
286
                .reset (rst_i),
287
                .read_address (tmem_read_address),
288
                .enable_read (read_port_enable),
289
                .write_address (tmem_write_address),
290
                .enable_write (`TRUE),
291
                .write_enable (way_tmem_we[i]),
292
                .write_data (tmem_write_data),
293
                // ----- Outputs -------
294
                .read_data ({way_tag[i], way_valid[i]})
295
                );
296
        end
297
 
298
   endgenerate
299
 
300
/////////////////////////////////////////////////////
301
// Combinational logic
302
/////////////////////////////////////////////////////
303
 
304
// Compute which ways in the cache match the address being read
305
generate
306
    for (i = 0; i < associativity; i = i + 1)
307
    begin : match
308
assign way_match[i] = ({way_tag[i], way_valid[i]} == {address_m[`LM32_DC_ADDR_TAG_RNG], `TRUE});
309
    end
310
endgenerate
311
 
312
// Select data from way that matched the address being read
313
generate
314
    if (associativity == 1)
315
         begin : data_1
316
assign load_data = way_data[0];
317
    end
318
    else if (associativity == 2)
319
         begin : data_2
320
assign load_data = way_match[0] ? way_data[0] : way_data[1];
321
    end
322
endgenerate
323
 
324
generate
325
    if (`LM32_DC_DMEM_ADDR_WIDTH < 11)
326
    begin
327
// Select data to write to data memories
328
always @(*)
329
begin
330
    if (refill == `TRUE)
331
        dmem_write_data = refill_data;
332
    else
333
    begin
334
        dmem_write_data[`LM32_BYTE_0_RNG] = store_byte_select[0] ? store_data[`LM32_BYTE_0_RNG] : load_data[`LM32_BYTE_0_RNG];
335
        dmem_write_data[`LM32_BYTE_1_RNG] = store_byte_select[1] ? store_data[`LM32_BYTE_1_RNG] : load_data[`LM32_BYTE_1_RNG];
336
        dmem_write_data[`LM32_BYTE_2_RNG] = store_byte_select[2] ? store_data[`LM32_BYTE_2_RNG] : load_data[`LM32_BYTE_2_RNG];
337
        dmem_write_data[`LM32_BYTE_3_RNG] = store_byte_select[3] ? store_data[`LM32_BYTE_3_RNG] : load_data[`LM32_BYTE_3_RNG];
338
    end
339
end
340
    end
341
    else
342
    begin
343
// Select data to write to data memories - FIXME: Should use different write ports on dual port RAMs, but they don't work
344
always @(*)
345
begin
346
    if (refill == `TRUE)
347
        dmem_write_data = refill_data;
348
    else
349
        dmem_write_data = store_data;
350
end
351
    end
352
endgenerate
353
 
354
// Compute address to use to index into the data memories
355
generate
356
     if (bytes_per_line > 4)
357
assign dmem_write_address = (refill == `TRUE)
358
                            ? {refill_address[`LM32_DC_ADDR_SET_RNG], refill_offset}
359
                            : address_m[`LM32_DC_ADDR_IDX_RNG];
360
    else
361
assign dmem_write_address = (refill == `TRUE)
362
                            ? refill_address[`LM32_DC_ADDR_SET_RNG]
363
                            : address_m[`LM32_DC_ADDR_IDX_RNG];
364
endgenerate
365
assign dmem_read_address = address_x[`LM32_DC_ADDR_IDX_RNG];
366
// Compute address to use to index into the tag memories
367
assign tmem_write_address = (flushing == `TRUE)
368
                            ? flush_set
369
                            : refill_address[`LM32_DC_ADDR_SET_RNG];
370
assign tmem_read_address = address_x[`LM32_DC_ADDR_SET_RNG];
371
 
372
// Compute signal to indicate when we are on the last refill accesses
373
generate
374
    if (bytes_per_line > 4)
375
assign last_refill = refill_offset == {addr_offset_width{1'b1}};
376
    else
377
assign last_refill = `TRUE;
378
endgenerate
379
 
380
// Compute data and tag memory access enable
381
assign read_port_enable = (stall_x == `FALSE);
382
assign write_port_enable = (refill_ready == `TRUE) || !stall_m;
383
 
384
// Determine when we have a valid store
385
assign valid_store = (store_q_m == `TRUE) && (check == `TRUE);
386
 
387
// Compute data and tag memory write enables
388
generate
389
    if (associativity == 1)
390
    begin : we_1
391
assign way_dmem_we[0] = (refill_ready == `TRUE) || ((valid_store == `TRUE) && (way_match[0] == `TRUE));
392
assign way_tmem_we[0] = (refill_ready == `TRUE) || (flushing == `TRUE);
393
    end
394
    else
395
    begin : we_2
396
assign way_dmem_we[0] = ((refill_ready == `TRUE) && (refill_way_select[0] == `TRUE)) || ((valid_store == `TRUE) && (way_match[0] == `TRUE));
397
assign way_dmem_we[1] = ((refill_ready == `TRUE) && (refill_way_select[1] == `TRUE)) || ((valid_store == `TRUE) && (way_match[1] == `TRUE));
398
assign way_tmem_we[0] = ((refill_ready == `TRUE) && (refill_way_select[0] == `TRUE)) || (flushing == `TRUE);
399
assign way_tmem_we[1] = ((refill_ready == `TRUE) && (refill_way_select[1] == `TRUE)) || (flushing == `TRUE);
400
    end
401
endgenerate
402
 
403
// On the last refill cycle set the valid bit, for all other writes it should be cleared
404
assign tmem_write_data[`LM32_DC_TAGS_VALID_RNG] = ((last_refill == `TRUE) || (valid_store == `TRUE)) && (flushing == `FALSE);
405
assign tmem_write_data[`LM32_DC_TAGS_TAG_RNG] = refill_address[`LM32_DC_ADDR_TAG_RNG];
406
 
407
// Signals that indicate which state we are in
408
assign flushing = state[0];
409
assign check = state[1];
410
assign refill = state[2];
411
 
412
assign miss = (~(|way_match)) && (load_q_m == `TRUE) && (stall_m == `FALSE)
413
`ifdef CFG_MMU_ENABLED
414
        && (~dtlb_miss_x)
415
`endif
416
        ;
417
assign stall_request = (check == `FALSE);
418
 
419
/////////////////////////////////////////////////////
420
// Sequential logic
421
/////////////////////////////////////////////////////
422
 
423
// Record way selected for replacement on a cache miss
424
generate
425
    if (associativity >= 2)
426
    begin : way_select
427
always @(posedge clk_i `CFG_RESET_SENSITIVITY)
428
begin
429
    if (rst_i == `TRUE)
430
        refill_way_select <= {{associativity-1{1'b0}}, 1'b1};
431
    else
432
    begin
433
        if (refill_request == `TRUE)
434
            refill_way_select <= {refill_way_select[0], refill_way_select[1]};
435
    end
436
end
437
    end
438
endgenerate
439
 
440
// Record whether we are currently refilling
441
always @(posedge clk_i `CFG_RESET_SENSITIVITY)
442
begin
443
    if (rst_i == `TRUE)
444
        refilling <= `FALSE;
445
    else
446
        refilling <= refill;
447
end
448
 
449
// Instruction cache control FSM
450
always @(posedge clk_i `CFG_RESET_SENSITIVITY)
451
begin
452
    if (rst_i == `TRUE)
453
    begin
454
        state <= `LM32_DC_STATE_FLUSH;
455
        flush_set <= {`LM32_DC_TMEM_ADDR_WIDTH{1'b1}};
456
        refill_request <= `FALSE;
457
        refill_address <= {`LM32_WORD_WIDTH{1'bx}};
458
        restart_request <= `FALSE;
459
    end
460
    else
461
    begin
462
        case (state)
463
 
464
        // Flush the cache
465
        `LM32_DC_STATE_FLUSH:
466
        begin
467
            if (flush_set == {`LM32_DC_TMEM_ADDR_WIDTH{1'b0}})
468
                state <= `LM32_DC_STATE_CHECK;
469
            flush_set <= flush_set - 1'b1;
470
        end
471
 
472
        // Check for cache misses
473
        `LM32_DC_STATE_CHECK:
474
        begin
475
            if (stall_a == `FALSE)
476
                restart_request <= `FALSE;
477
            if (miss == `TRUE)
478
            begin
479
                refill_request <= `TRUE;
480
                refill_address <= address_m;
481
                state <= `LM32_DC_STATE_REFILL;
482
            end
483
            else if (dflush == `TRUE)
484
                state <= `LM32_DC_STATE_FLUSH;
485
        end
486
 
487
        // Refill a cache line
488
        `LM32_DC_STATE_REFILL:
489
        begin
490
            refill_request <= `FALSE;
491
            if (refill_ready == `TRUE)
492
            begin
493
                if (last_refill == `TRUE)
494
                begin
495
                    restart_request <= `TRUE;
496
                    state <= `LM32_DC_STATE_CHECK;
497
                end
498
            end
499
        end
500
 
501
        endcase
502
    end
503
end
504
 
505
generate
506
    if (bytes_per_line > 4)
507
    begin
508
// Refill offset
509
always @(posedge clk_i `CFG_RESET_SENSITIVITY)
510
begin
511
    if (rst_i == `TRUE)
512
        refill_offset <= {addr_offset_width{1'b0}};
513
    else
514
    begin
515
        case (state)
516
 
517
        // Check for cache misses
518
        `LM32_DC_STATE_CHECK:
519
        begin
520
            if (miss == `TRUE)
521
                refill_offset <= {addr_offset_width{1'b0}};
522
        end
523
 
524
        // Refill a cache line
525
        `LM32_DC_STATE_REFILL:
526
        begin
527
            if (refill_ready == `TRUE)
528
                refill_offset <= refill_offset + 1'b1;
529
        end
530
 
531
        endcase
532
    end
533
end
534
    end
535
endgenerate
536
 
537
endmodule
538
 
539
`endif
540
 

powered by: WebSVN 2.1.0

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