rtl/lm32_icache.v

Sat, 06 Aug 2011 01:34:41 +0100

author
Philip Pemberton <philpem@philpem.me.uk>
date
Sat, 06 Aug 2011 01:34:41 +0100
changeset 30
614f58128bcc
parent 28
da23ab8ef7b4
permissions
-rw-r--r--

Merge LM32 v3.8 docs in

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