Root/lm32/logic/sakc/rtl/lm32/lm32_dcache.v

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

Archive Download this file

Branches:
master



interactive