| 1 | 1327 | jcastillo | //////////////////////////////////////////////////////////////////////
 | 
      
         | 2 |  |  | ////                                                              ////
 | 
      
         | 3 |  |  | ////  OR1200's IC FSM                                             ////
 | 
      
         | 4 |  |  | ////                                                              ////
 | 
      
         | 5 |  |  | ////  This file is part of the OpenRISC 1200 project              ////
 | 
      
         | 6 |  |  | ////  http://www.opencores.org/cores/or1k/                        ////
 | 
      
         | 7 |  |  | ////                                                              ////
 | 
      
         | 8 |  |  | ////  Description                                                 ////
 | 
      
         | 9 |  |  | ////  Insn cache state machine                                    ////
 | 
      
         | 10 |  |  | ////                                                              ////
 | 
      
         | 11 |  |  | ////  To Do:                                                      ////
 | 
      
         | 12 |  |  | ////   - make it smaller and faster                               ////
 | 
      
         | 13 |  |  | ////                                                              ////
 | 
      
         | 14 |  |  | ////  Author(s):                                                  ////
 | 
      
         | 15 |  |  | ////      - Damjan Lampret, lampret@opencores.org                 ////
 | 
      
         | 16 |  |  | ////                                                              ////
 | 
      
         | 17 |  |  | //////////////////////////////////////////////////////////////////////
 | 
      
         | 18 |  |  | ////                                                              ////
 | 
      
         | 19 |  |  | //// Copyright (C) 2000 Authors and OPENCORES.ORG                 ////
 | 
      
         | 20 |  |  | ////                                                              ////
 | 
      
         | 21 |  |  | //// This source file may be used and distributed without         ////
 | 
      
         | 22 |  |  | //// restriction provided that this copyright statement is not    ////
 | 
      
         | 23 |  |  | //// removed from the file and that any derivative work contains  ////
 | 
      
         | 24 |  |  | //// the original copyright notice and the associated disclaimer. ////
 | 
      
         | 25 |  |  | ////                                                              ////
 | 
      
         | 26 |  |  | //// This source file is free software; you can redistribute it   ////
 | 
      
         | 27 |  |  | //// and/or modify it under the terms of the GNU Lesser General   ////
 | 
      
         | 28 |  |  | //// Public License as published by the Free Software Foundation; ////
 | 
      
         | 29 |  |  | //// either version 2.1 of the License, or (at your option) any   ////
 | 
      
         | 30 |  |  | //// later version.                                               ////
 | 
      
         | 31 |  |  | ////                                                              ////
 | 
      
         | 32 |  |  | //// This source is distributed in the hope that it will be       ////
 | 
      
         | 33 |  |  | //// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
 | 
      
         | 34 |  |  | //// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
 | 
      
         | 35 |  |  | //// PURPOSE.  See the GNU Lesser General Public License for more ////
 | 
      
         | 36 |  |  | //// details.                                                     ////
 | 
      
         | 37 |  |  | ////                                                              ////
 | 
      
         | 38 |  |  | //// You should have received a copy of the GNU Lesser General    ////
 | 
      
         | 39 |  |  | //// Public License along with this source; if not, download it   ////
 | 
      
         | 40 |  |  | //// from http://www.opencores.org/lgpl.shtml                     ////
 | 
      
         | 41 |  |  | ////                                                              ////
 | 
      
         | 42 |  |  | //////////////////////////////////////////////////////////////////////
 | 
      
         | 43 |  |  | //
 | 
      
         | 44 |  |  | // CVS Revision History
 | 
      
         | 45 |  |  | //
 | 
      
         | 46 |  |  | // $Log: not supported by cvs2svn $
 | 
      
         | 47 |  |  | // Revision 1.10  2004/06/08 18:17:36  lampret
 | 
      
         | 48 |  |  | // Non-functional changes. Coding style fixes.
 | 
      
         | 49 |  |  | //
 | 
      
         | 50 |  |  | // Revision 1.9  2004/04/05 08:29:57  lampret
 | 
      
         | 51 |  |  | // Merged branch_qmem into main tree.
 | 
      
         | 52 |  |  | //
 | 
      
         | 53 |  |  | // Revision 1.8.4.1  2003/07/08 15:36:37  lampret
 | 
      
         | 54 |  |  | // Added embedded memory QMEM.
 | 
      
         | 55 |  |  | //
 | 
      
         | 56 |  |  | // Revision 1.8  2003/06/06 02:54:47  lampret
 | 
      
         | 57 |  |  | // When OR1200_NO_IMMU and OR1200_NO_IC are not both defined or undefined at the same time, results in a IC bug. Fixed.
 | 
      
         | 58 |  |  | //
 | 
      
         | 59 |  |  | // Revision 1.7  2002/03/29 15:16:55  lampret
 | 
      
         | 60 |  |  | // Some of the warnings fixed.
 | 
      
         | 61 |  |  | //
 | 
      
         | 62 |  |  | // Revision 1.6  2002/03/28 19:10:40  lampret
 | 
      
         | 63 |  |  | // Optimized cache controller FSM.
 | 
      
         | 64 |  |  | //
 | 
      
         | 65 |  |  | // Revision 1.1.1.1  2002/03/21 16:55:45  lampret
 | 
      
         | 66 |  |  | // First import of the "new" XESS XSV environment.
 | 
      
         | 67 |  |  | //
 | 
      
         | 68 |  |  | //
 | 
      
         | 69 |  |  | // Revision 1.5  2002/02/11 04:33:17  lampret
 | 
      
         | 70 |  |  | // Speed optimizations (removed duplicate _cyc_ and _stb_). Fixed D/IMMU cache-inhibit attr.
 | 
      
         | 71 |  |  | //
 | 
      
         | 72 |  |  | // Revision 1.4  2002/02/01 19:56:54  lampret
 | 
      
         | 73 |  |  | // Fixed combinational loops.
 | 
      
         | 74 |  |  | //
 | 
      
         | 75 |  |  | // Revision 1.3  2002/01/28 01:16:00  lampret
 | 
      
         | 76 |  |  | // Changed 'void' nop-ops instead of insn[0] to use insn[16]. Debug unit stalls the tick timer. Prepared new flag generation for add and and insns. Blocked DC/IC while they are turned off. Fixed I/D MMU SPRs layout except WAYs. TODO: smart IC invalidate, l.j 2 and TLB ways.
 | 
      
         | 77 |  |  | //
 | 
      
         | 78 |  |  | // Revision 1.2  2002/01/14 06:18:22  lampret
 | 
      
         | 79 |  |  | // Fixed mem2reg bug in FAST implementation. Updated debug unit to work with new genpc/if.
 | 
      
         | 80 |  |  | //
 | 
      
         | 81 |  |  | // Revision 1.1  2002/01/03 08:16:15  lampret
 | 
      
         | 82 |  |  | // New prefixes for RTL files, prefixed module names. Updated cache controllers and MMUs.
 | 
      
         | 83 |  |  | //
 | 
      
         | 84 |  |  | // Revision 1.9  2001/10/21 17:57:16  lampret
 | 
      
         | 85 |  |  | // Removed params from generic_XX.v. Added translate_off/on in sprs.v and id.v. Removed spr_addr from ic.v and ic.v. Fixed CR+LF.
 | 
      
         | 86 |  |  | //
 | 
      
         | 87 |  |  | // Revision 1.8  2001/10/19 23:28:46  lampret
 | 
      
         | 88 |  |  | // Fixed some synthesis warnings. Configured with caches and MMUs.
 | 
      
         | 89 |  |  | //
 | 
      
         | 90 |  |  | // Revision 1.7  2001/10/14 13:12:09  lampret
 | 
      
         | 91 |  |  | // MP3 version.
 | 
      
         | 92 |  |  | //
 | 
      
         | 93 |  |  | // Revision 1.1.1.1  2001/10/06 10:18:35  igorm
 | 
      
         | 94 |  |  | // no message
 | 
      
         | 95 |  |  | //
 | 
      
         | 96 |  |  | // Revision 1.2  2001/08/09 13:39:33  lampret
 | 
      
         | 97 |  |  | // Major clean-up.
 | 
      
         | 98 |  |  | //
 | 
      
         | 99 |  |  | // Revision 1.1  2001/07/20 00:46:03  lampret
 | 
      
         | 100 |  |  | // Development version of RTL. Libraries are missing.
 | 
      
         | 101 |  |  | //
 | 
      
         | 102 |  |  | //
 | 
      
         | 103 |  |  |  
 | 
      
         | 104 |  |  | // synopsys translate_off
 | 
      
         | 105 |  |  | `include "timescale.v"
 | 
      
         | 106 |  |  | // synopsys translate_on
 | 
      
         | 107 |  |  | `include "or1200_defines.v"
 | 
      
         | 108 |  |  |  
 | 
      
         | 109 |  |  | `define OR1200_ICFSM_IDLE       2'd0
 | 
      
         | 110 |  |  | `define OR1200_ICFSM_CFETCH     2'd1
 | 
      
         | 111 |  |  | `define OR1200_ICFSM_LREFILL3   2'd2
 | 
      
         | 112 |  |  | `define OR1200_ICFSM_IFETCH     2'd3
 | 
      
         | 113 |  |  |  
 | 
      
         | 114 |  |  | //
 | 
      
         | 115 |  |  | // Data cache FSM for cache line of 16 bytes (4x singleword)
 | 
      
         | 116 |  |  | //
 | 
      
         | 117 |  |  |  
 | 
      
         | 118 |  |  | module or1200_ic_fsm(
 | 
      
         | 119 |  |  |         // Clock and reset
 | 
      
         | 120 |  |  |         clk, rst,
 | 
      
         | 121 |  |  |  
 | 
      
         | 122 |  |  |         // Internal i/f to top level IC
 | 
      
         | 123 |  |  |         ic_en, icqmem_cycstb_i, icqmem_ci_i,
 | 
      
         | 124 |  |  |         tagcomp_miss, biudata_valid, biudata_error, start_addr, saved_addr,
 | 
      
         | 125 |  |  |         icram_we, biu_read, first_hit_ack, first_miss_ack, first_miss_err,
 | 
      
         | 126 |  |  |         burst, tag_we
 | 
      
         | 127 |  |  | );
 | 
      
         | 128 |  |  |  
 | 
      
         | 129 |  |  | //
 | 
      
         | 130 |  |  | // I/O
 | 
      
         | 131 |  |  | //
 | 
      
         | 132 |  |  | input                           clk;
 | 
      
         | 133 |  |  | input                           rst;
 | 
      
         | 134 |  |  | input                           ic_en;
 | 
      
         | 135 |  |  | input                           icqmem_cycstb_i;
 | 
      
         | 136 |  |  | input                           icqmem_ci_i;
 | 
      
         | 137 |  |  | input                           tagcomp_miss;
 | 
      
         | 138 |  |  | input                           biudata_valid;
 | 
      
         | 139 |  |  | input                           biudata_error;
 | 
      
         | 140 |  |  | input   [31:0]                   start_addr;
 | 
      
         | 141 |  |  | output  [31:0]                   saved_addr;
 | 
      
         | 142 |  |  | output  [3:0]                    icram_we;
 | 
      
         | 143 |  |  | output                          biu_read;
 | 
      
         | 144 |  |  | output                          first_hit_ack;
 | 
      
         | 145 |  |  | output                          first_miss_ack;
 | 
      
         | 146 |  |  | output                          first_miss_err;
 | 
      
         | 147 |  |  | output                          burst;
 | 
      
         | 148 |  |  | output                          tag_we;
 | 
      
         | 149 |  |  |  
 | 
      
         | 150 |  |  | //
 | 
      
         | 151 |  |  | // Internal wires and regs
 | 
      
         | 152 |  |  | //
 | 
      
         | 153 |  |  | reg     [31:0]                   saved_addr_r;
 | 
      
         | 154 |  |  | reg     [1:0]                    state;
 | 
      
         | 155 |  |  | reg     [2:0]                    cnt;
 | 
      
         | 156 |  |  | reg                             hitmiss_eval;
 | 
      
         | 157 |  |  | reg                             load;
 | 
      
         | 158 |  |  | reg                             cache_inhibit;
 | 
      
         | 159 |  |  |  
 | 
      
         | 160 |  |  | //
 | 
      
         | 161 |  |  | // Generate of ICRAM write enables
 | 
      
         | 162 |  |  | //
 | 
      
         | 163 |  |  | assign icram_we = {4{biu_read & biudata_valid & !cache_inhibit}};
 | 
      
         | 164 |  |  | assign tag_we = biu_read & biudata_valid & !cache_inhibit;
 | 
      
         | 165 |  |  |  
 | 
      
         | 166 |  |  | //
 | 
      
         | 167 |  |  | // BIU read and write
 | 
      
         | 168 |  |  | //
 | 
      
         | 169 |  |  | assign biu_read = (hitmiss_eval & tagcomp_miss) | (!hitmiss_eval & load);
 | 
      
         | 170 |  |  |  
 | 
      
         | 171 |  |  | //assign saved_addr = hitmiss_eval ? start_addr : saved_addr_r;
 | 
      
         | 172 |  |  | assign saved_addr = saved_addr_r;
 | 
      
         | 173 |  |  |  
 | 
      
         | 174 |  |  | //
 | 
      
         | 175 |  |  | // Assert for cache hit first word ready
 | 
      
         | 176 |  |  | // Assert for cache miss first word stored/loaded OK
 | 
      
         | 177 |  |  | // Assert for cache miss first word stored/loaded with an error
 | 
      
         | 178 |  |  | //
 | 
      
         | 179 |  |  | assign first_hit_ack = (state == `OR1200_ICFSM_CFETCH) & hitmiss_eval & !tagcomp_miss & !cache_inhibit & !icqmem_ci_i;
 | 
      
         | 180 |  |  | assign first_miss_ack = (state == `OR1200_ICFSM_CFETCH) & biudata_valid;
 | 
      
         | 181 |  |  | assign first_miss_err = (state == `OR1200_ICFSM_CFETCH) & biudata_error;
 | 
      
         | 182 |  |  |  
 | 
      
         | 183 |  |  | //
 | 
      
         | 184 |  |  | // Assert burst when doing reload of complete cache line
 | 
      
         | 185 |  |  | //
 | 
      
         | 186 |  |  | assign burst = (state == `OR1200_ICFSM_CFETCH) & tagcomp_miss & !cache_inhibit
 | 
      
         | 187 |  |  |                 | (state == `OR1200_ICFSM_LREFILL3);
 | 
      
         | 188 |  |  |  
 | 
      
         | 189 |  |  | //
 | 
      
         | 190 |  |  | // Main IC FSM
 | 
      
         | 191 |  |  | //
 | 
      
         | 192 |  |  | always @(posedge clk or posedge rst) begin
 | 
      
         | 193 |  |  |         if (rst) begin
 | 
      
         | 194 |  |  |                 state <= #1 `OR1200_ICFSM_IDLE;
 | 
      
         | 195 |  |  |                 saved_addr_r <= #1 32'b0;
 | 
      
         | 196 |  |  |                 hitmiss_eval <= #1 1'b0;
 | 
      
         | 197 |  |  |                 load <= #1 1'b0;
 | 
      
         | 198 |  |  |                 cnt <= #1 3'b000;
 | 
      
         | 199 |  |  |                 cache_inhibit <= #1 1'b0;
 | 
      
         | 200 |  |  |         end
 | 
      
         | 201 |  |  |         else
 | 
      
         | 202 |  |  |         case (state)    // synopsys parallel_case
 | 
      
         | 203 |  |  |                 `OR1200_ICFSM_IDLE :
 | 
      
         | 204 |  |  |                         if (ic_en & icqmem_cycstb_i) begin              // fetch
 | 
      
         | 205 |  |  |                                 state <= #1 `OR1200_ICFSM_CFETCH;
 | 
      
         | 206 |  |  |                                 saved_addr_r <= #1 start_addr;
 | 
      
         | 207 |  |  |                                 hitmiss_eval <= #1 1'b1;
 | 
      
         | 208 |  |  |                                 load <= #1 1'b1;
 | 
      
         | 209 |  |  |                                 cache_inhibit <= #1 1'b0;
 | 
      
         | 210 |  |  |                         end
 | 
      
         | 211 |  |  |                         else begin                                                      // idle
 | 
      
         | 212 |  |  |                                 hitmiss_eval <= #1 1'b0;
 | 
      
         | 213 |  |  |                                 load <= #1 1'b0;
 | 
      
         | 214 |  |  |                                 cache_inhibit <= #1 1'b0;
 | 
      
         | 215 |  |  |                         end
 | 
      
         | 216 |  |  |                 `OR1200_ICFSM_CFETCH: begin     // fetch
 | 
      
         | 217 |  |  |                         if (icqmem_cycstb_i & icqmem_ci_i)
 | 
      
         | 218 |  |  |                                 cache_inhibit <= #1 1'b1;
 | 
      
         | 219 |  |  |                         if (hitmiss_eval)
 | 
      
         | 220 |  |  |                                 saved_addr_r[31:13] <= #1 start_addr[31:13];
 | 
      
         | 221 |  |  |                         if ((!ic_en) ||
 | 
      
         | 222 |  |  |                             (hitmiss_eval & !icqmem_cycstb_i) ||        // fetch aborted (usually caused by IMMU)
 | 
      
         | 223 |  |  |                             (biudata_error) ||                                          // fetch terminated with an error
 | 
      
         | 224 |  |  |                             (cache_inhibit & biudata_valid)) begin      // fetch from cache-inhibited page
 | 
      
         | 225 |  |  |                                 state <= #1 `OR1200_ICFSM_IDLE;
 | 
      
         | 226 |  |  |                                 hitmiss_eval <= #1 1'b0;
 | 
      
         | 227 |  |  |                                 load <= #1 1'b0;
 | 
      
         | 228 |  |  |                                 cache_inhibit <= #1 1'b0;
 | 
      
         | 229 |  |  |                         end
 | 
      
         | 230 |  |  |                         else if (tagcomp_miss & biudata_valid) begin    // fetch missed, finish current external fetch and refill
 | 
      
         | 231 |  |  |                                 state <= #1 `OR1200_ICFSM_LREFILL3;
 | 
      
         | 232 |  |  |                                 saved_addr_r[3:2] <= #1 saved_addr_r[3:2] + 1'd1;
 | 
      
         | 233 |  |  |                                 hitmiss_eval <= #1 1'b0;
 | 
      
         | 234 |  |  |                                 cnt <= #1 `OR1200_ICLS-2;
 | 
      
         | 235 |  |  |                                 cache_inhibit <= #1 1'b0;
 | 
      
         | 236 |  |  |                         end
 | 
      
         | 237 |  |  |                         else if (!tagcomp_miss & !icqmem_ci_i) begin    // fetch hit, finish immediately
 | 
      
         | 238 |  |  |                                 saved_addr_r <= #1 start_addr;
 | 
      
         | 239 |  |  |                                 cache_inhibit <= #1 1'b0;
 | 
      
         | 240 |  |  |                         end
 | 
      
         | 241 |  |  |                         else if (!icqmem_cycstb_i) begin        // fetch aborted (usually caused by exception)
 | 
      
         | 242 |  |  |                                 state <= #1 `OR1200_ICFSM_IDLE;
 | 
      
         | 243 |  |  |                                 hitmiss_eval <= #1 1'b0;
 | 
      
         | 244 |  |  |                                 load <= #1 1'b0;
 | 
      
         | 245 |  |  |                                 cache_inhibit <= #1 1'b0;
 | 
      
         | 246 |  |  |                         end
 | 
      
         | 247 |  |  |                         else                                            // fetch in-progress
 | 
      
         | 248 |  |  |                                 hitmiss_eval <= #1 1'b0;
 | 
      
         | 249 |  |  |                 end
 | 
      
         | 250 |  |  |                 `OR1200_ICFSM_LREFILL3 : begin
 | 
      
         | 251 |  |  |                         if (biudata_valid && (|cnt)) begin              // refill ack, more fetchs to come
 | 
      
         | 252 |  |  |                                 cnt <= #1 cnt - 3'd1;
 | 
      
         | 253 |  |  |                                 saved_addr_r[3:2] <= #1 saved_addr_r[3:2] + 1'd1;
 | 
      
         | 254 |  |  |                         end
 | 
      
         | 255 |  |  |                         else if (biudata_valid) begin                   // last fetch of line refill
 | 
      
         | 256 |  |  |                                 state <= #1 `OR1200_ICFSM_IDLE;
 | 
      
         | 257 |  |  |                                 saved_addr_r <= #1 start_addr;
 | 
      
         | 258 |  |  |                                 hitmiss_eval <= #1 1'b0;
 | 
      
         | 259 |  |  |                                 load <= #1 1'b0;
 | 
      
         | 260 |  |  |                         end
 | 
      
         | 261 |  |  |                 end
 | 
      
         | 262 |  |  |                 default:
 | 
      
         | 263 |  |  |                         state <= #1 `OR1200_ICFSM_IDLE;
 | 
      
         | 264 |  |  |         endcase
 | 
      
         | 265 |  |  | end
 | 
      
         | 266 |  |  |  
 | 
      
         | 267 |  |  | endmodule
 |