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).

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