lm32_icache.v

Mon, 05 Apr 2010 21:00:31 +0100

author
Philip Pemberton <philpem@philpem.me.uk>
date
Mon, 05 Apr 2010 21:00:31 +0100
changeset 6
a8e459b24c31
parent 3
b153470d41c5
permissions
-rw-r--r--

reduce size of caches to fit in DE1 FPGA

The default cache size makes the Icache and Dcache "just a bit" too big to
fit in the EP2C20 FPGA on the DE1 board. This commit reduces the Icache and
Dcache sizes to the defaults shown in the LatticeMico32 Processor Reference
Manual (pages 36 and 37).

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