Root/lm32/logic/sakc/rtl/lm32/lm32_icache.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_icache.v
19// Title : Instruction cache
20// Dependencies : lm32_include.v
21// Version : 6.1.17
22// =============================================================================
23                      
24`include "lm32_include.v"
25
26`define LM32_IC_ADDR_OFFSET_RNG addr_offset_msb:addr_offset_lsb
27`define LM32_IC_ADDR_SET_RNG addr_set_msb:addr_set_lsb
28`define LM32_IC_ADDR_TAG_RNG addr_tag_msb:addr_tag_lsb
29`define LM32_IC_ADDR_IDX_RNG addr_set_msb:addr_offset_lsb
30
31`define LM32_IC_TMEM_ADDR_WIDTH addr_set_width
32`define LM32_IC_TMEM_ADDR_RNG (`LM32_IC_TMEM_ADDR_WIDTH-1):0
33`define LM32_IC_DMEM_ADDR_WIDTH (addr_offset_width+addr_set_width)
34`define LM32_IC_DMEM_ADDR_RNG (`LM32_IC_DMEM_ADDR_WIDTH-1):0
35
36`define LM32_IC_TAGS_WIDTH (addr_tag_width+1)
37`define LM32_IC_TAGS_RNG (`LM32_IC_TAGS_WIDTH-1):0
38`define LM32_IC_TAGS_TAG_RNG (`LM32_IC_TAGS_WIDTH-1):1
39`define LM32_IC_TAGS_VALID_RNG 0
40
41`define LM32_IC_STATE_RNG 3:0
42`define LM32_IC_STATE_FLUSH_INIT 4'b0001
43`define LM32_IC_STATE_FLUSH 4'b0010
44`define LM32_IC_STATE_CHECK 4'b0100
45`define LM32_IC_STATE_REFILL 4'b1000
46
47/////////////////////////////////////////////////////
48// Module interface
49/////////////////////////////////////////////////////
50
51module lm32_icache (
52    // ----- Inputs -----
53    clk_i,
54    rst_i,
55    stall_a,
56    stall_f,
57    address_a,
58    address_f,
59    read_enable_f,
60    refill_ready,
61    refill_data,
62    iflush,
63    // ----- Outputs -----
64    stall_request,
65    restart_request,
66    refill_request,
67    refill_address,
68    refilling,
69    inst
70    );
71
72/////////////////////////////////////////////////////
73// Parameters
74/////////////////////////////////////////////////////
75
76parameter associativity = 1; // Associativity of the cache (Number of ways)
77parameter sets = 512; // Number of sets
78parameter bytes_per_line = 16; // Number of bytes per cache line
79parameter base_address = 0; // Base address of cachable memory
80parameter limit = 0; // Limit (highest address) of cachable memory
81
82localparam addr_offset_width = 2;
83localparam addr_set_width = 9;
84localparam addr_offset_lsb = 2;
85localparam addr_offset_msb = (addr_offset_lsb+addr_offset_width-1);
86localparam addr_set_lsb = (addr_offset_msb+1);
87localparam addr_set_msb = (addr_set_lsb+addr_set_width-1);
88localparam addr_tag_lsb = (addr_set_msb+1);
89localparam addr_tag_msb = 31;
90localparam addr_tag_width = (addr_tag_msb-addr_tag_lsb+1);
91
92/////////////////////////////////////////////////////
93// Inputs
94/////////////////////////////////////////////////////
95
96input clk_i; // Clock
97input rst_i; // Reset
98
99input stall_a; // Stall instruction in A stage
100input stall_f; // Stall instruction in F stage
101
102input [`LM32_PC_RNG] address_a; // Address of instruction in A stage
103input [`LM32_PC_RNG] address_f; // Address of instruction in F stage
104input read_enable_f; // Indicates if cache access is valid
105
106input refill_ready; // Next word of refill data is ready
107input [`LM32_INSTRUCTION_RNG] refill_data; // Data to refill the cache with
108
109input iflush; // Flush the cache
110
111/////////////////////////////////////////////////////
112// Outputs
113/////////////////////////////////////////////////////
114
115output stall_request; // Request to stall the pipeline
116wire stall_request;
117output restart_request; // Request to restart instruction that caused the cache miss
118reg restart_request;
119output refill_request; // Request to refill a cache line
120wire refill_request;
121output [`LM32_PC_RNG] refill_address; // Base address of cache refill
122reg [`LM32_PC_RNG] refill_address;
123output refilling; // Indicates the instruction cache is currently refilling
124reg refilling;
125output [`LM32_INSTRUCTION_RNG] inst; // Instruction read from cache
126wire [`LM32_INSTRUCTION_RNG] inst;
127
128/////////////////////////////////////////////////////
129// Internal nets and registers
130/////////////////////////////////////////////////////
131
132wire enable;
133wire [0:associativity-1] way_mem_we;
134wire [`LM32_INSTRUCTION_RNG] way_data[0:associativity-1];
135wire [`LM32_IC_TAGS_TAG_RNG] way_tag[0:associativity-1];
136wire [0:associativity-1] way_valid;
137wire [0:associativity-1] way_match;
138wire miss;
139
140wire [`LM32_IC_TMEM_ADDR_RNG] tmem_read_address;
141wire [`LM32_IC_TMEM_ADDR_RNG] tmem_write_address;
142wire [`LM32_IC_DMEM_ADDR_RNG] dmem_read_address;
143wire [`LM32_IC_DMEM_ADDR_RNG] dmem_write_address;
144wire [`LM32_IC_TAGS_RNG] tmem_write_data;
145
146reg [`LM32_IC_STATE_RNG] state;
147wire flushing;
148wire check;
149wire refill;
150
151reg [associativity-1:0] refill_way_select;
152reg [`LM32_IC_ADDR_OFFSET_RNG] refill_offset;
153wire last_refill;
154reg [`LM32_IC_TMEM_ADDR_RNG] flush_set;
155
156genvar i;
157
158/////////////////////////////////////////////////////
159// Functions
160/////////////////////////////////////////////////////
161
162`include "lm32_functions.v"
163
164/////////////////////////////////////////////////////
165// Instantiations
166/////////////////////////////////////////////////////
167
168generate
169    for (i = 0; i < associativity; i = i + 1)
170    begin : memories
171
172// Way 0 data
173lm32_ram #(
174    // ----- Parameters -------
175    .data_width (32),
176    .address_width (`LM32_IC_DMEM_ADDR_WIDTH)
177  ) way_0_data_ram (
178    // ----- Inputs -------
179    .read_clk (clk_i),
180    .write_clk (clk_i),
181    .reset (rst_i),
182    .read_address (dmem_read_address),
183    .enable_read (enable),
184    .write_address (dmem_write_address),
185    .enable_write (`TRUE),
186    .write_enable (way_mem_we[i]),
187    .write_data (refill_data),
188    // ----- Outputs -------
189    .read_data (way_data[i])
190    );
191
192// Way 0 tags
193lm32_ram #(
194    // ----- Parameters -------
195    .data_width (`LM32_IC_TAGS_WIDTH),
196    .address_width (`LM32_IC_TMEM_ADDR_WIDTH)
197  ) way_0_tag_ram (
198    // ----- Inputs -------
199    .read_clk (clk_i),
200    .write_clk (clk_i),
201    .reset (rst_i),
202    .read_address (tmem_read_address),
203    .enable_read (enable),
204    .write_address (tmem_write_address),
205    .enable_write (`TRUE),
206    .write_enable (way_mem_we[i] | flushing),
207    .write_data (tmem_write_data),
208    // ----- Outputs -------
209    .read_data ({way_tag[i], way_valid[i]})
210    );
211
212    end
213endgenerate
214
215/////////////////////////////////////////////////////
216// Combinational logic
217/////////////////////////////////////////////////////
218
219// Compute which ways in the cache match the address address being read
220generate
221    for (i = 0; i < associativity; i = i + 1)
222    begin : match
223assign way_match[i] = ({way_tag[i], way_valid[i]} == {address_f[`LM32_IC_ADDR_TAG_RNG], `TRUE});
224    end
225endgenerate
226
227// Select data from way that matched the address being read
228generate
229    if (associativity == 1)
230    begin : inst_1
231assign inst = way_data[0];
232    end
233    else if (associativity == 2)
234     begin : inst_2
235assign inst = way_match[0] ? way_data[0] : way_data[1];
236    end
237endgenerate
238
239// Compute address to use to index into the data memories
240generate
241    if (bytes_per_line > 4)
242    begin : wadr1
243assign dmem_write_address = {refill_address[`LM32_IC_ADDR_SET_RNG], refill_offset};
244    end
245    else
246    begin : wadr2
247assign dmem_write_address = refill_address[`LM32_IC_ADDR_SET_RNG];
248    end
249endgenerate
250    
251assign dmem_read_address = address_a[`LM32_IC_ADDR_IDX_RNG];
252
253// Compute address to use to index into the tag memories
254assign tmem_read_address = address_a[`LM32_IC_ADDR_SET_RNG];
255assign tmem_write_address = flushing
256                                ? flush_set
257                                : refill_address[`LM32_IC_ADDR_SET_RNG];
258
259// Compute signal to indicate when we are on the last refill accesses
260generate
261    if (bytes_per_line > 4)
262    begin : lrefil1
263assign last_refill = refill_offset == {addr_offset_width{1'b1}};
264    end
265    else
266    begin : lrefil2
267assign last_refill = `TRUE;
268    end
269endgenerate
270
271// Compute data and tag memory access enable
272assign enable = (stall_a == `FALSE);
273
274// Compute data and tag memory write enables
275generate
276    if (associativity == 1)
277    begin : we_1
278assign way_mem_we[0] = (refill_ready == `TRUE);
279    end
280    else
281    begin : we_2
282assign way_mem_we[0] = (refill_ready == `TRUE) && (refill_way_select[0] == `TRUE);
283assign way_mem_we[1] = (refill_ready == `TRUE) && (refill_way_select[1] == `TRUE);
284    end
285endgenerate
286
287// On the last refill cycle set the valid bit, for all other writes it should be cleared
288assign tmem_write_data[`LM32_IC_TAGS_VALID_RNG] = last_refill & !flushing;
289assign tmem_write_data[`LM32_IC_TAGS_TAG_RNG] = refill_address[`LM32_IC_ADDR_TAG_RNG];
290
291// Signals that indicate which state we are in
292assign flushing = |state[1:0];
293assign check = state[2];
294assign refill = state[3];
295
296assign miss = (~(|way_match)) && (read_enable_f == `TRUE) && (stall_f == `FALSE);
297assign stall_request = (check == `FALSE);
298assign refill_request = (refill == `TRUE);
299                      
300/////////////////////////////////////////////////////
301// Sequential logic
302/////////////////////////////////////////////////////
303
304// Record way selected for replacement on a cache miss
305generate
306    if (associativity >= 2)
307    begin : way_select
308always @(posedge clk_i `CFG_RESET_SENSITIVITY)
309begin
310    if (rst_i == `TRUE)
311        refill_way_select <= {{associativity-1{1'b0}}, 1'b1};
312    else
313    begin
314        if (miss == `TRUE)
315            refill_way_select <= {refill_way_select[0], refill_way_select[1]};
316    end
317end
318    end
319endgenerate
320
321// Record whether we are refilling
322always @(posedge clk_i `CFG_RESET_SENSITIVITY)
323begin
324    if (rst_i == `TRUE)
325        refilling <= `FALSE;
326    else
327        refilling <= refill;
328end
329
330// Instruction cache control FSM
331always @(posedge clk_i `CFG_RESET_SENSITIVITY)
332begin
333    if (rst_i == `TRUE)
334    begin
335        state <= `LM32_IC_STATE_FLUSH_INIT;
336        flush_set <= {`LM32_IC_TMEM_ADDR_WIDTH{1'b1}};
337        refill_address <= {`LM32_PC_WIDTH{1'bx}};
338        restart_request <= `FALSE;
339    end
340    else
341    begin
342        case (state)
343
344        // Flush the cache for the first time after reset
345        `LM32_IC_STATE_FLUSH_INIT:
346        begin
347            if (flush_set == {`LM32_IC_TMEM_ADDR_WIDTH{1'b0}})
348                state <= `LM32_IC_STATE_CHECK;
349            flush_set <= flush_set - 1'b1;
350        end
351
352        // Flush the cache in response to an write to the ICC CSR
353        `LM32_IC_STATE_FLUSH:
354        begin
355            if (flush_set == {`LM32_IC_TMEM_ADDR_WIDTH{1'b0}})
356                state <= `LM32_IC_STATE_REFILL;
357            flush_set <= flush_set - 1'b1;
358        end
359        
360        // Check for cache misses
361        `LM32_IC_STATE_CHECK:
362        begin
363            if (stall_a == `FALSE)
364                restart_request <= `FALSE;
365            if (iflush == `TRUE)
366            begin
367                refill_address <= address_f;
368                state <= `LM32_IC_STATE_FLUSH;
369            end
370            else if (miss == `TRUE)
371            begin
372                refill_address <= address_f;
373                state <= `LM32_IC_STATE_REFILL;
374            end
375        end
376
377        // Refill a cache line
378        `LM32_IC_STATE_REFILL:
379        begin
380            if (refill_ready == `TRUE)
381            begin
382                if (last_refill == `TRUE)
383                begin
384                    restart_request <= `TRUE;
385                    state <= `LM32_IC_STATE_CHECK;
386                end
387            end
388        end
389
390        endcase
391    end
392end
393
394generate
395    if (bytes_per_line > 4)
396    begin : refilof1
397// Refill offset
398always @(posedge clk_i `CFG_RESET_SENSITIVITY)
399begin
400    if (rst_i == `TRUE)
401        refill_offset <= {addr_offset_width{1'b0}};
402    else
403    begin
404        case (state)
405        
406        // Check for cache misses
407        `LM32_IC_STATE_CHECK:
408        begin
409            if (iflush == `TRUE)
410                refill_offset <= {addr_offset_width{1'b0}};
411            else if (miss == `TRUE)
412                refill_offset <= {addr_offset_width{1'b0}};
413        end
414
415        // Refill a cache line
416        `LM32_IC_STATE_REFILL:
417        begin
418            if (refill_ready == `TRUE)
419                refill_offset <= refill_offset + 1'b1;
420        end
421
422        endcase
423    end
424end
425    end
426endgenerate
427   
428endmodule
429

Archive Download this file

Branches:
master



interactive