[6] | 1 | // ========== Copyright Header Begin ========================================== |
---|
| 2 | // |
---|
| 3 | // OpenSPARC T1 Processor File: sparc_ifu_invctl.v |
---|
| 4 | // Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. |
---|
| 5 | // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES. |
---|
| 6 | // |
---|
| 7 | // The above named program is free software; you can redistribute it and/or |
---|
| 8 | // modify it under the terms of the GNU General Public |
---|
| 9 | // License version 2 as published by the Free Software Foundation. |
---|
| 10 | // |
---|
| 11 | // The above named program is distributed in the hope that it will be |
---|
| 12 | // useful, but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
| 13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
---|
| 14 | // General Public License for more details. |
---|
| 15 | // |
---|
| 16 | // You should have received a copy of the GNU General Public |
---|
| 17 | // License along with this work; if not, write to the Free Software |
---|
| 18 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. |
---|
| 19 | // |
---|
| 20 | // ========== Copyright Header End ============================================ |
---|
| 21 | /////////////////////////////////////////////////////////////////////// |
---|
| 22 | /* |
---|
| 23 | // Module Name: sparc_ifu_invctl |
---|
| 24 | // Description: |
---|
| 25 | // Control logic for handling invalidations to the icache |
---|
| 26 | // |
---|
| 27 | */ |
---|
| 28 | |
---|
| 29 | //////////////////////////////////////////////////////////////////////// |
---|
| 30 | // Global header file includes |
---|
| 31 | //////////////////////////////////////////////////////////////////////// |
---|
| 32 | |
---|
| 33 | `include "iop.h" |
---|
| 34 | `include "ifu.h" |
---|
| 35 | |
---|
| 36 | module sparc_ifu_invctl(/*AUTOARG*/ |
---|
| 37 | // Outputs |
---|
| 38 | so, inv_ifc_inv_pending, ifq_icv_wrindex_bf, ifq_icv_wren_bf, |
---|
| 39 | ifq_ict_dec_wrway_bf, ifq_fcl_invreq_bf, ifq_erb_asiway_f, |
---|
| 40 | // Inputs |
---|
| 41 | rclk, se, si, const_cpuid, mbist_icache_write, |
---|
| 42 | lsu_ifu_ld_icache_index, lsu_ifu_ld_pcxpkt_vld, |
---|
| 43 | lsu_ifu_ld_pcxpkt_tid, ifc_inv_ifqadv_i2, ifc_inv_asireq_i2, |
---|
| 44 | ifq_icd_index_bf, ifd_inv_ifqop_i2, ifd_inv_wrway_i2 |
---|
| 45 | ); |
---|
| 46 | |
---|
| 47 | input rclk, |
---|
| 48 | se, |
---|
| 49 | si; |
---|
| 50 | |
---|
| 51 | |
---|
| 52 | input [2:0] const_cpuid; |
---|
| 53 | input mbist_icache_write; |
---|
| 54 | |
---|
| 55 | input [`IC_IDX_HI:5] lsu_ifu_ld_icache_index; |
---|
| 56 | input lsu_ifu_ld_pcxpkt_vld; |
---|
| 57 | input [1:0] lsu_ifu_ld_pcxpkt_tid; |
---|
| 58 | |
---|
| 59 | input ifc_inv_ifqadv_i2; |
---|
| 60 | input ifc_inv_asireq_i2; |
---|
| 61 | |
---|
| 62 | input [`IC_IDX_HI:5] ifq_icd_index_bf; |
---|
| 63 | input [`CPX_WIDTH-1:0] ifd_inv_ifqop_i2; |
---|
| 64 | input [1:0] ifd_inv_wrway_i2; |
---|
| 65 | |
---|
| 66 | |
---|
| 67 | output so; |
---|
| 68 | |
---|
| 69 | output inv_ifc_inv_pending; |
---|
| 70 | |
---|
| 71 | output [`IC_IDX_HI:5] ifq_icv_wrindex_bf; |
---|
| 72 | output [15:0] ifq_icv_wren_bf; |
---|
| 73 | output [3:0] ifq_ict_dec_wrway_bf; |
---|
| 74 | output ifq_fcl_invreq_bf; |
---|
| 75 | output [1:0] ifq_erb_asiway_f; |
---|
| 76 | |
---|
| 77 | |
---|
| 78 | //---------------------------------------------------------------------- |
---|
| 79 | // Local Signals |
---|
| 80 | //---------------------------------------------------------------------- |
---|
| 81 | |
---|
| 82 | wire [3:0] cpu_sel, |
---|
| 83 | invcpu21_sel_i2; |
---|
| 84 | wire invcpu0_sel_i2; |
---|
| 85 | |
---|
| 86 | wire [1:0] inv_vec0, |
---|
| 87 | inv_vec1; |
---|
| 88 | wire [1:0] inv_way0_p1_i2, |
---|
| 89 | inv_way0_p0_i2, |
---|
| 90 | inv_way1_p1_i2, |
---|
| 91 | inv_way1_p0_i2, |
---|
| 92 | invwd0_way_i2, |
---|
| 93 | invwd1_way_i2, |
---|
| 94 | inv0_way_i2, |
---|
| 95 | inv1_way_i2; |
---|
| 96 | |
---|
| 97 | wire [1:0] asi_way_f; |
---|
| 98 | |
---|
| 99 | wire word0_inv_i2, |
---|
| 100 | word1_inv_i2; |
---|
| 101 | |
---|
| 102 | wire ldinv_i2, |
---|
| 103 | ldpkt_i2, |
---|
| 104 | evpkt_i2, |
---|
| 105 | stpkt_i2, |
---|
| 106 | strmack_i2, |
---|
| 107 | imissrtn_i2; |
---|
| 108 | |
---|
| 109 | wire invreq_i2, |
---|
| 110 | invalidate_i2, |
---|
| 111 | invalidate_f; |
---|
| 112 | |
---|
| 113 | wire invall_i2, |
---|
| 114 | invpa5_i2; |
---|
| 115 | |
---|
| 116 | wire [1:0] cpxthrid_i2; |
---|
| 117 | wire [3:0] dcpxthr_i2; |
---|
| 118 | |
---|
| 119 | wire [1:0] ldinv_way_i2; |
---|
| 120 | wire [1:0] w0_way_i2, |
---|
| 121 | w1_way_i2, |
---|
| 122 | w0_way_f, |
---|
| 123 | w1_way_f; |
---|
| 124 | |
---|
| 125 | wire pick_wr; |
---|
| 126 | wire icv_wrreq_i2; |
---|
| 127 | |
---|
| 128 | wire [3:0] wrt_en_wd_i2, |
---|
| 129 | wrt_en_wd_bf, |
---|
| 130 | wrt_en_wd_f; |
---|
| 131 | |
---|
| 132 | wire [3:0] w0_dec_way_i2, |
---|
| 133 | w1_dec_way_i2; |
---|
| 134 | |
---|
| 135 | wire [3:0] dec_wrway; |
---|
| 136 | |
---|
| 137 | wire icvidx_sel_wr_i2, |
---|
| 138 | icvidx_sel_ld_i2, |
---|
| 139 | icvidx_sel_inv_i2; |
---|
| 140 | |
---|
| 141 | wire [15:0] wren_i2; |
---|
| 142 | |
---|
| 143 | |
---|
| 144 | wire [`IC_IDX_HI:6] inv_addr_i2; |
---|
| 145 | wire [`IC_IDX_HI:5] icaddr_i2; |
---|
| 146 | |
---|
| 147 | wire missaddr5_i2; |
---|
| 148 | wire missaddr6_i2; |
---|
| 149 | |
---|
| 150 | |
---|
| 151 | wire [3:0] ldthr, |
---|
| 152 | ldidx_sel_new; |
---|
| 153 | |
---|
| 154 | wire [`IC_IDX_HI:5] ldinv_addr_i2, |
---|
| 155 | ldindex0, |
---|
| 156 | ldindex1, |
---|
| 157 | ldindex2, |
---|
| 158 | ldindex3, |
---|
| 159 | ldindex0_nxt, |
---|
| 160 | ldindex1_nxt, |
---|
| 161 | ldindex2_nxt, |
---|
| 162 | ldindex3_nxt; |
---|
| 163 | |
---|
| 164 | wire clk; |
---|
| 165 | |
---|
| 166 | |
---|
| 167 | // |
---|
| 168 | // Code Begins Here |
---|
| 169 | // |
---|
| 170 | assign clk = rclk; |
---|
| 171 | |
---|
| 172 | //---------------------------------------------------------------------- |
---|
| 173 | // Extract Invalidate Packet For This Core |
---|
| 174 | //---------------------------------------------------------------------- |
---|
| 175 | |
---|
| 176 | // mux the invalidate vector down to get this processors inv vector |
---|
| 177 | |
---|
| 178 | // First ecode cpu id |
---|
| 179 | assign cpu_sel[0] = ~const_cpuid[2] & ~const_cpuid[1]; |
---|
| 180 | assign cpu_sel[1] = ~const_cpuid[2] & const_cpuid[1]; |
---|
| 181 | assign cpu_sel[2] = const_cpuid[2] & ~const_cpuid[1]; |
---|
| 182 | assign cpu_sel[3] = const_cpuid[2] & const_cpuid[1]; |
---|
| 183 | |
---|
| 184 | // 4:1 follwed by 2:1 to get 8:1, to get invalidate way selects |
---|
| 185 | assign invcpu21_sel_i2 = cpu_sel; |
---|
| 186 | assign invcpu0_sel_i2 = const_cpuid[0]; |
---|
| 187 | |
---|
| 188 | // First do word 0 for even processors |
---|
| 189 | mux4ds #(1) v0p0_mux(.dout (inv_vec0[0]), |
---|
| 190 | .in0 (ifd_inv_ifqop_i2[1]), |
---|
| 191 | .in1 (ifd_inv_ifqop_i2[9]), |
---|
| 192 | .in2 (ifd_inv_ifqop_i2[17]), |
---|
| 193 | .in3 (ifd_inv_ifqop_i2[25]), |
---|
| 194 | .sel0 (invcpu21_sel_i2[0]), |
---|
| 195 | .sel1 (invcpu21_sel_i2[1]), |
---|
| 196 | .sel2 (invcpu21_sel_i2[2]), |
---|
| 197 | .sel3 (invcpu21_sel_i2[3])); |
---|
| 198 | |
---|
| 199 | mux4ds #(2) w0p0_mux(.dout (inv_way0_p0_i2[1:0]), |
---|
| 200 | .in0 (ifd_inv_ifqop_i2[3:2]), |
---|
| 201 | .in1 (ifd_inv_ifqop_i2[11:10]), |
---|
| 202 | .in2 (ifd_inv_ifqop_i2[19:18]), |
---|
| 203 | .in3 (ifd_inv_ifqop_i2[27:26]), |
---|
| 204 | .sel0 (invcpu21_sel_i2[0]), |
---|
| 205 | .sel1 (invcpu21_sel_i2[1]), |
---|
| 206 | .sel2 (invcpu21_sel_i2[2]), |
---|
| 207 | .sel3 (invcpu21_sel_i2[3])); |
---|
| 208 | |
---|
| 209 | // word 0 for odd processors |
---|
| 210 | mux4ds #(1) v0p1_mux(.dout (inv_vec0[1]), |
---|
| 211 | .in0 (ifd_inv_ifqop_i2[5]), |
---|
| 212 | .in1 (ifd_inv_ifqop_i2[13]), |
---|
| 213 | .in2 (ifd_inv_ifqop_i2[21]), |
---|
| 214 | .in3 (ifd_inv_ifqop_i2[29]), |
---|
| 215 | .sel0 (invcpu21_sel_i2[0]), |
---|
| 216 | .sel1 (invcpu21_sel_i2[1]), |
---|
| 217 | .sel2 (invcpu21_sel_i2[2]), |
---|
| 218 | .sel3 (invcpu21_sel_i2[3])); |
---|
| 219 | |
---|
| 220 | mux4ds #(2) w0p1_mux(.dout (inv_way0_p1_i2[1:0]), |
---|
| 221 | .in0 (ifd_inv_ifqop_i2[7:6]), |
---|
| 222 | .in1 (ifd_inv_ifqop_i2[15:14]), |
---|
| 223 | .in2 (ifd_inv_ifqop_i2[23:22]), |
---|
| 224 | .in3 (ifd_inv_ifqop_i2[31:30]), |
---|
| 225 | .sel0 (invcpu21_sel_i2[0]), |
---|
| 226 | .sel1 (invcpu21_sel_i2[1]), |
---|
| 227 | .sel2 (invcpu21_sel_i2[2]), |
---|
| 228 | .sel3 (invcpu21_sel_i2[3])); |
---|
| 229 | |
---|
| 230 | |
---|
| 231 | // Word 1 |
---|
| 232 | // word 1 for even processors |
---|
| 233 | mux4ds #(1) v1p0_mux(.dout (inv_vec1[0]), |
---|
| 234 | .in0 (ifd_inv_ifqop_i2[57]), |
---|
| 235 | .in1 (ifd_inv_ifqop_i2[65]), |
---|
| 236 | .in2 (ifd_inv_ifqop_i2[73]), |
---|
| 237 | .in3 (ifd_inv_ifqop_i2[81]), |
---|
| 238 | .sel0 (invcpu21_sel_i2[0]), |
---|
| 239 | .sel1 (invcpu21_sel_i2[1]), |
---|
| 240 | .sel2 (invcpu21_sel_i2[2]), |
---|
| 241 | .sel3 (invcpu21_sel_i2[3])); |
---|
| 242 | |
---|
| 243 | mux4ds #(2) w1p0_mux(.dout (inv_way1_p0_i2[1:0]), |
---|
| 244 | .in0 (ifd_inv_ifqop_i2[59:58]), |
---|
| 245 | .in1 (ifd_inv_ifqop_i2[67:66]), |
---|
| 246 | .in2 (ifd_inv_ifqop_i2[75:74]), |
---|
| 247 | .in3 (ifd_inv_ifqop_i2[83:82]), |
---|
| 248 | .sel0 (invcpu21_sel_i2[0]), |
---|
| 249 | .sel1 (invcpu21_sel_i2[1]), |
---|
| 250 | .sel2 (invcpu21_sel_i2[2]), |
---|
| 251 | .sel3 (invcpu21_sel_i2[3])); |
---|
| 252 | |
---|
| 253 | // word 1 for odd processors |
---|
| 254 | mux4ds #(1) inv_v1p1_mux(.dout (inv_vec1[1]), |
---|
| 255 | .in0 (ifd_inv_ifqop_i2[61]), |
---|
| 256 | .in1 (ifd_inv_ifqop_i2[69]), |
---|
| 257 | .in2 (ifd_inv_ifqop_i2[77]), |
---|
| 258 | .in3 (ifd_inv_ifqop_i2[85]), |
---|
| 259 | .sel0 (invcpu21_sel_i2[0]), |
---|
| 260 | .sel1 (invcpu21_sel_i2[1]), |
---|
| 261 | .sel2 (invcpu21_sel_i2[2]), |
---|
| 262 | .sel3 (invcpu21_sel_i2[3])); |
---|
| 263 | |
---|
| 264 | mux4ds #(2) w1p1_mux(.dout (inv_way1_p1_i2[1:0]), |
---|
| 265 | .in0 (ifd_inv_ifqop_i2[63:62]), |
---|
| 266 | .in1 (ifd_inv_ifqop_i2[71:70]), |
---|
| 267 | .in2 (ifd_inv_ifqop_i2[79:78]), |
---|
| 268 | .in3 (ifd_inv_ifqop_i2[87:86]), |
---|
| 269 | .sel0 (invcpu21_sel_i2[0]), |
---|
| 270 | .sel1 (invcpu21_sel_i2[1]), |
---|
| 271 | .sel2 (invcpu21_sel_i2[2]), |
---|
| 272 | .sel3 (invcpu21_sel_i2[3])); |
---|
| 273 | |
---|
| 274 | // Mux odd and even values down to a single value for word0 and word1 |
---|
| 275 | // dp_mux2es #(1) v0_mux (.dout (word0_inv_i2), |
---|
| 276 | // .in0 (inv_vec0[0]), |
---|
| 277 | // .in1 (inv_vec0[1]), |
---|
| 278 | // .sel (invcpu0_sel_i2)); |
---|
| 279 | assign word0_inv_i2 = invcpu0_sel_i2 ? inv_vec0[1] : inv_vec0[0]; |
---|
| 280 | |
---|
| 281 | // dp_mux2es #(2) w0_mux (.dout (invwd0_way_i2[1:0]), |
---|
| 282 | // .in0 (inv_way0_p0_i2[1:0]), |
---|
| 283 | // .in1 (inv_way0_p1_i2[1:0]), |
---|
| 284 | // .sel (invcpu0_sel_i2)); |
---|
| 285 | assign invwd0_way_i2 = invcpu0_sel_i2 ? inv_way0_p1_i2[1:0] : |
---|
| 286 | inv_way0_p0_i2[1:0]; |
---|
| 287 | |
---|
| 288 | // word1 |
---|
| 289 | // dp_mux2es #(1) v1_mux (.dout (word1_inv_i2), |
---|
| 290 | // .in0 (inv_vec1[0]), |
---|
| 291 | // .in1 (inv_vec1[1]), |
---|
| 292 | // .sel (invcpu0_sel_i2)); |
---|
| 293 | assign word1_inv_i2 = invcpu0_sel_i2 ? inv_vec1[1] : inv_vec1[0]; |
---|
| 294 | |
---|
| 295 | // dp_mux2es #(2) w1_mux (.dout (invwd1_way_i2[1:0]), |
---|
| 296 | // .in0 (inv_way1_p0_i2[1:0]), |
---|
| 297 | // .in1 (inv_way1_p1_i2[1:0]), |
---|
| 298 | // .sel (invcpu0_sel_i2)); |
---|
| 299 | assign invwd1_way_i2 = invcpu0_sel_i2 ? inv_way1_p1_i2[1:0] : |
---|
| 300 | inv_way1_p0_i2[1:0]; |
---|
| 301 | |
---|
| 302 | //----------------------------- |
---|
| 303 | // Decode CPX Packet |
---|
| 304 | //----------------------------- |
---|
| 305 | // load |
---|
| 306 | assign ldpkt_i2 = ({ifd_inv_ifqop_i2[`CPX_VLD], |
---|
| 307 | ifd_inv_ifqop_i2[`CPX_REQFIELD]} == `CPX_LDPKT) ? |
---|
| 308 | 1'b1 : 1'b0; |
---|
| 309 | assign ldinv_i2 = ldpkt_i2 & ifd_inv_ifqop_i2[`CPX_WYVLD]; |
---|
| 310 | assign ldinv_way_i2= ifd_inv_ifqop_i2[`CPX_WY_HI:`CPX_WY_LO]; |
---|
| 311 | |
---|
| 312 | // ifill |
---|
| 313 | assign imissrtn_i2 = ({ifd_inv_ifqop_i2[`CPX_VLD], |
---|
| 314 | ifd_inv_ifqop_i2[`CPX_REQFIELD]} == `CPX_IFILLPKT) ? |
---|
| 315 | 1'b1 : 1'b0; |
---|
| 316 | |
---|
| 317 | // store ack |
---|
| 318 | assign stpkt_i2 = ({ifd_inv_ifqop_i2[`CPX_VLD], |
---|
| 319 | ifd_inv_ifqop_i2[`CPX_REQFIELD]} == `CPX_STRPKT) ? |
---|
| 320 | 1'b1 : 1'b0; |
---|
| 321 | assign strmack_i2 = ({ifd_inv_ifqop_i2[`CPX_VLD], |
---|
| 322 | ifd_inv_ifqop_i2[`CPX_REQFIELD]} == `CPX_STRMACK) ? |
---|
| 323 | 1'b1 : 1'b0; |
---|
| 324 | assign invall_i2 = stpkt_i2 & ifd_inv_ifqop_i2[`CPX_IINV] & |
---|
| 325 | ifc_inv_ifqadv_i2; |
---|
| 326 | assign invpa5_i2 = ifd_inv_ifqop_i2[`CPX_INVPA5]; |
---|
| 327 | |
---|
| 328 | // evict |
---|
| 329 | assign evpkt_i2 = ({ifd_inv_ifqop_i2[`CPX_VLD], |
---|
| 330 | ifd_inv_ifqop_i2[`CPX_REQFIELD]} == `CPX_EVPKT) ? |
---|
| 331 | 1'b1 : 1'b0; |
---|
| 332 | |
---|
| 333 | // get thread id and decode |
---|
| 334 | assign cpxthrid_i2 = ifd_inv_ifqop_i2[`CPX_THRFIELD]; |
---|
| 335 | |
---|
| 336 | assign dcpxthr_i2[0] = ~cpxthrid_i2[1] & ~cpxthrid_i2[0]; |
---|
| 337 | assign dcpxthr_i2[1] = ~cpxthrid_i2[1] & cpxthrid_i2[0]; |
---|
| 338 | assign dcpxthr_i2[2] = cpxthrid_i2[1] & ~cpxthrid_i2[0]; |
---|
| 339 | assign dcpxthr_i2[3] = cpxthrid_i2[1] & cpxthrid_i2[0]; |
---|
| 340 | |
---|
| 341 | //----------------------------------------------- |
---|
| 342 | // Generate Write Way and Write Enables |
---|
| 343 | //----------------------------------------------- |
---|
| 344 | |
---|
| 345 | // decode way for tags |
---|
| 346 | assign dec_wrway[0] = ~ifd_inv_wrway_i2[1] & ~ifd_inv_wrway_i2[0]; |
---|
| 347 | assign dec_wrway[1] = ~ifd_inv_wrway_i2[1] & ifd_inv_wrway_i2[0]; |
---|
| 348 | assign dec_wrway[2] = ifd_inv_wrway_i2[1] & ~ifd_inv_wrway_i2[0]; |
---|
| 349 | assign dec_wrway[3] = ifd_inv_wrway_i2[1] & ifd_inv_wrway_i2[0]; |
---|
| 350 | |
---|
| 351 | assign ifq_ict_dec_wrway_bf = dec_wrway; |
---|
| 352 | |
---|
| 353 | // way for asi |
---|
| 354 | dff_s #(2) asiwayf_reg(.din (ifd_inv_wrway_i2), |
---|
| 355 | .q (asi_way_f), |
---|
| 356 | .clk (clk), .se(se), .si(), .so()); |
---|
| 357 | |
---|
| 358 | assign ifq_erb_asiway_f = asi_way_f; |
---|
| 359 | |
---|
| 360 | |
---|
| 361 | // Select which index/way to invalidate |
---|
| 362 | assign icv_wrreq_i2 = imissrtn_i2 | ifc_inv_asireq_i2 | mbist_icache_write; |
---|
| 363 | |
---|
| 364 | assign inv0_way_i2 = ~ifc_inv_ifqadv_i2 ? w0_way_f : |
---|
| 365 | ldinv_i2 ? ldinv_way_i2 : |
---|
| 366 | invwd0_way_i2; |
---|
| 367 | assign inv1_way_i2 = ~ifc_inv_ifqadv_i2 ? w1_way_f : |
---|
| 368 | ldinv_i2 ? ldinv_way_i2 : |
---|
| 369 | invwd1_way_i2; |
---|
| 370 | |
---|
| 371 | assign pick_wr = (imissrtn_i2 | ifc_inv_asireq_i2) & ifc_inv_ifqadv_i2 | |
---|
| 372 | mbist_icache_write; |
---|
| 373 | assign w0_way_i2 = pick_wr ? ifd_inv_wrway_i2 : |
---|
| 374 | inv0_way_i2; |
---|
| 375 | assign w1_way_i2 = pick_wr ? ifd_inv_wrway_i2 : |
---|
| 376 | inv1_way_i2; |
---|
| 377 | |
---|
| 378 | dff_s #(4) wrway_reg(.din ({w0_way_i2, w1_way_i2}), |
---|
| 379 | .q ({w0_way_f, w1_way_f}), |
---|
| 380 | .clk (clk), .se(se), .si(), .so()); |
---|
| 381 | |
---|
| 382 | // determine the way in the ICV we are writing to |
---|
| 383 | // mux3ds #(2) w0_waymux(.dout (w0_way_i2), |
---|
| 384 | // .in0 (ifd_inv_wrway_i2[1:0]), |
---|
| 385 | // .in1 (invwd0_way_i2[1:0]), |
---|
| 386 | // .in2 (ldinv_way_i2[1:0]), |
---|
| 387 | // .sel0 (icvidx_sel_wr_i2), |
---|
| 388 | // .sel1 (icvidx_sel_inv_i2), |
---|
| 389 | // .sel2 (icvidx_sel_ld_i2)); |
---|
| 390 | |
---|
| 391 | // mux3ds #(2) w1_waymux(.dout (w1_way_i2), |
---|
| 392 | // .in0 (ifd_inv_wrway_i2[1:0]), |
---|
| 393 | // .in1 (invwd1_way_i2[1:0]), |
---|
| 394 | // .in2 (ldinv_way_i2[1:0]), |
---|
| 395 | // .sel0 (icvidx_sel_wr_i2), |
---|
| 396 | // .sel1 (icvidx_sel_inv_i2), |
---|
| 397 | // .sel2 (icvidx_sel_ld_i2)); |
---|
| 398 | |
---|
| 399 | // decode write way |
---|
| 400 | assign w0_dec_way_i2[0] = ~w0_way_i2[1] & ~w0_way_i2[0]; |
---|
| 401 | assign w0_dec_way_i2[1] = ~w0_way_i2[1] & w0_way_i2[0]; |
---|
| 402 | assign w0_dec_way_i2[2] = w0_way_i2[1] & ~w0_way_i2[0]; |
---|
| 403 | assign w0_dec_way_i2[3] = w0_way_i2[1] & w0_way_i2[0]; |
---|
| 404 | |
---|
| 405 | assign w1_dec_way_i2[0] = ~w1_way_i2[1] & ~w1_way_i2[0]; |
---|
| 406 | assign w1_dec_way_i2[1] = ~w1_way_i2[1] & w1_way_i2[0]; |
---|
| 407 | assign w1_dec_way_i2[2] = w1_way_i2[1] & ~w1_way_i2[0]; |
---|
| 408 | assign w1_dec_way_i2[3] = w1_way_i2[1] & w1_way_i2[0]; |
---|
| 409 | |
---|
| 410 | |
---|
| 411 | // determine if valid bit write to top 32B, bot 32B or both |
---|
| 412 | assign wrt_en_wd_i2[0] = word0_inv_i2 & (stpkt_i2 | evpkt_i2 |strmack_i2) & |
---|
| 413 | ~inv_addr_i2[6] | |
---|
| 414 | ldinv_i2 & ~ldinv_addr_i2[5] & ~ldinv_addr_i2[6] | |
---|
| 415 | icv_wrreq_i2 & ~missaddr5_i2 & ~missaddr6_i2; |
---|
| 416 | |
---|
| 417 | assign wrt_en_wd_i2[1] = word1_inv_i2 & (stpkt_i2 | evpkt_i2 |strmack_i2) & |
---|
| 418 | ~inv_addr_i2[6] | |
---|
| 419 | ldinv_i2 & ldinv_addr_i2[5] & ~ldinv_addr_i2[6] | |
---|
| 420 | icv_wrreq_i2 & missaddr5_i2 & ~missaddr6_i2; |
---|
| 421 | |
---|
| 422 | assign wrt_en_wd_i2[2] = word0_inv_i2 & (stpkt_i2 | evpkt_i2 |strmack_i2) & |
---|
| 423 | inv_addr_i2[6] | |
---|
| 424 | ldinv_i2 & ~ldinv_addr_i2[5] & ldinv_addr_i2[6] | |
---|
| 425 | icv_wrreq_i2 & ~missaddr5_i2 & missaddr6_i2; |
---|
| 426 | |
---|
| 427 | assign wrt_en_wd_i2[3] = word1_inv_i2 & (stpkt_i2 | evpkt_i2 |strmack_i2) & |
---|
| 428 | inv_addr_i2[6] | |
---|
| 429 | ldinv_i2 & ldinv_addr_i2[5] & ldinv_addr_i2[6] | |
---|
| 430 | icv_wrreq_i2 & missaddr5_i2 & missaddr6_i2; |
---|
| 431 | |
---|
| 432 | assign wrt_en_wd_bf = ifc_inv_ifqadv_i2 ? wrt_en_wd_i2 : |
---|
| 433 | wrt_en_wd_f; |
---|
| 434 | dff_s #(4) wrten_reg(.din (wrt_en_wd_bf), |
---|
| 435 | .q (wrt_en_wd_f), |
---|
| 436 | .clk (clk), .se(se), .si(), .so()); |
---|
| 437 | |
---|
| 438 | |
---|
| 439 | // Final Write Enable to ICV |
---|
| 440 | assign wren_i2[3:0] = (w0_dec_way_i2 & {4{wrt_en_wd_bf[0]}}) | |
---|
| 441 | {4{invall_i2 & ~invpa5_i2 & ~inv_addr_i2[6]}}; |
---|
| 442 | |
---|
| 443 | assign wren_i2[7:4] = (w1_dec_way_i2 & {4{wrt_en_wd_bf[1]}}) | |
---|
| 444 | {4{invall_i2 & invpa5_i2 & ~inv_addr_i2[6]}}; |
---|
| 445 | |
---|
| 446 | assign wren_i2[11:8] = (w0_dec_way_i2 & {4{wrt_en_wd_bf[2]}}) | |
---|
| 447 | {4{invall_i2 & ~invpa5_i2 & inv_addr_i2[6]}}; |
---|
| 448 | |
---|
| 449 | assign wren_i2[15:12] = (w1_dec_way_i2 & {4{wrt_en_wd_bf[3]}}) | |
---|
| 450 | {4{invall_i2 & invpa5_i2 & inv_addr_i2[6]}}; |
---|
| 451 | |
---|
| 452 | assign ifq_icv_wren_bf = wren_i2; |
---|
| 453 | |
---|
| 454 | // advance the wr way for the ICV array |
---|
| 455 | // mux2ds #(8) wren_mux(.dout (next_wren_i2), |
---|
| 456 | // .in0 (wren_f), |
---|
| 457 | // .in1 (wren_i2), |
---|
| 458 | // .sel0 (~ifc_ifd_ifqadv_i2), |
---|
| 459 | // .sel1 (ifc_ifd_ifqadv_i2)); |
---|
| 460 | |
---|
| 461 | // assign wren_bf = ifc_inv_ifqadv_i2 ? wren_i2 : wren_f; |
---|
| 462 | // dff #(8) icv_weff(.din (wren_bf), |
---|
| 463 | // .q (wren_f), |
---|
| 464 | // .clk (clk), |
---|
| 465 | // .se (se), .si(), .so()); |
---|
| 466 | |
---|
| 467 | // assign ifq_icv_wren_bf[7:0] = wren_bf[7:0] & {8{~icvaddr6_i2}}; |
---|
| 468 | // assign ifq_icv_wren_bf[15:8] = wren_bf[7:0] & {8{icvaddr6_i2}}; |
---|
| 469 | |
---|
| 470 | |
---|
| 471 | //-------------------------- |
---|
| 472 | // Invalidates |
---|
| 473 | //-------------------------- |
---|
| 474 | assign invalidate_i2 = (stpkt_i2 | evpkt_i2 | strmack_i2) & |
---|
| 475 | (word0_inv_i2 | |
---|
| 476 | word1_inv_i2 | |
---|
| 477 | ifd_inv_ifqop_i2[`CPX_IINV]) | // all ways |
---|
| 478 | ldinv_i2; |
---|
| 479 | |
---|
| 480 | mux2ds #(1) invf_mux(.dout (invreq_i2), |
---|
| 481 | .in0 (invalidate_f), |
---|
| 482 | .in1 (invalidate_i2), |
---|
| 483 | .sel0 (~ifc_inv_ifqadv_i2), |
---|
| 484 | .sel1 (ifc_inv_ifqadv_i2)); |
---|
| 485 | |
---|
| 486 | dff_s #(1) invf_ff(.din (invreq_i2), |
---|
| 487 | .q (invalidate_f), |
---|
| 488 | .clk (clk), |
---|
| 489 | .se (se), .si(), .so()); |
---|
| 490 | |
---|
| 491 | // auto invalidate is done during bist |
---|
| 492 | // no need to qualify bist_write with ifqadv_i2 since bist is done |
---|
| 493 | // before anything else. |
---|
| 494 | assign ifq_fcl_invreq_bf = invreq_i2 | mbist_icache_write; |
---|
| 495 | |
---|
| 496 | // don't really need to OR with invalidate_f, since this will be |
---|
| 497 | // gone in a cycle |
---|
| 498 | // assign inv_ifc_inv_pending = invalidate_i2 | invalidate_f; |
---|
| 499 | assign inv_ifc_inv_pending = invalidate_i2; |
---|
| 500 | |
---|
| 501 | //--------------------------------- |
---|
| 502 | // Get the ifill/invalidation index |
---|
| 503 | //--------------------------------- |
---|
| 504 | |
---|
| 505 | // ifill index |
---|
| 506 | assign icaddr_i2[`IC_IDX_HI:5] = ifq_icd_index_bf[`IC_IDX_HI:5]; |
---|
| 507 | assign missaddr5_i2 = ifq_icd_index_bf[5]; |
---|
| 508 | assign missaddr6_i2 = ifq_icd_index_bf[6]; |
---|
| 509 | |
---|
| 510 | // evict invalidate index |
---|
| 511 | // assign inv_addr_i2 = ifqop_i2[117:112]; |
---|
| 512 | assign inv_addr_i2 = ifd_inv_ifqop_i2[`CPX_INV_IDX_HI:`CPX_INV_IDX_LO]; |
---|
| 513 | |
---|
| 514 | // index for invalidates caused by a load |
---|
| 515 | // store dcache index when a load req is made |
---|
| 516 | |
---|
| 517 | assign ldthr[0] = ~lsu_ifu_ld_pcxpkt_tid[1] & ~lsu_ifu_ld_pcxpkt_tid[0]; |
---|
| 518 | assign ldthr[1] = ~lsu_ifu_ld_pcxpkt_tid[1] & lsu_ifu_ld_pcxpkt_tid[0]; |
---|
| 519 | assign ldthr[2] = lsu_ifu_ld_pcxpkt_tid[1] & ~lsu_ifu_ld_pcxpkt_tid[0]; |
---|
| 520 | assign ldthr[3] = lsu_ifu_ld_pcxpkt_tid[1] & lsu_ifu_ld_pcxpkt_tid[0]; |
---|
| 521 | |
---|
| 522 | assign ldidx_sel_new = ldthr & {4{lsu_ifu_ld_pcxpkt_vld}}; |
---|
| 523 | |
---|
| 524 | // dp_mux2es #(`IC_IDX_SZ) t0_ldidx_mux(.dout (ldindex0_nxt), |
---|
| 525 | // .in0 (ldindex0), |
---|
| 526 | // .in1 (lsu_ifu_ld_icache_index), |
---|
| 527 | // .sel (ldidx_sel_new[0])); |
---|
| 528 | assign ldindex0_nxt = ldidx_sel_new[0] ? lsu_ifu_ld_icache_index : |
---|
| 529 | ldindex0; |
---|
| 530 | |
---|
| 531 | // dp_mux2es #(`IC_IDX_SZ) t1_ldidx_mux(.dout (ldindex1_nxt), |
---|
| 532 | // .in0 (ldindex1), |
---|
| 533 | // .in1 (lsu_ifu_ld_icache_index), |
---|
| 534 | // .sel (ldidx_sel_new[1])); |
---|
| 535 | assign ldindex1_nxt = ldidx_sel_new[1] ? lsu_ifu_ld_icache_index : |
---|
| 536 | ldindex1; |
---|
| 537 | |
---|
| 538 | // dp_mux2es #(`IC_IDX_SZ) t2_ldidx_mux(.dout (ldindex2_nxt), |
---|
| 539 | // .in0 (ldindex2), |
---|
| 540 | // .in1 (lsu_ifu_ld_icache_index), |
---|
| 541 | // .sel (ldidx_sel_new[2])); |
---|
| 542 | assign ldindex2_nxt = ldidx_sel_new[2] ? lsu_ifu_ld_icache_index : |
---|
| 543 | ldindex2; |
---|
| 544 | |
---|
| 545 | // dp_mux2es #(`IC_IDX_SZ) t3_ldidx_mux(.dout (ldindex3_nxt), |
---|
| 546 | // .in0 (ldindex3), |
---|
| 547 | // .in1 (lsu_ifu_ld_icache_index), |
---|
| 548 | // .sel (ldidx_sel_new[3])); |
---|
| 549 | assign ldindex3_nxt = ldidx_sel_new[3] ? lsu_ifu_ld_icache_index : |
---|
| 550 | ldindex3; |
---|
| 551 | |
---|
| 552 | |
---|
| 553 | dff_s #(`IC_IDX_SZ) ldix0_reg(.din (ldindex0_nxt), |
---|
| 554 | .q (ldindex0), |
---|
| 555 | .clk (clk), .se(se), .si(), .so()); |
---|
| 556 | dff_s #(`IC_IDX_SZ) ldix1_reg(.din (ldindex1_nxt), |
---|
| 557 | .q (ldindex1), |
---|
| 558 | .clk (clk), .se(se), .si(), .so()); |
---|
| 559 | dff_s #(`IC_IDX_SZ) ldix2_reg(.din (ldindex2_nxt), |
---|
| 560 | .q (ldindex2), |
---|
| 561 | .clk (clk), .se(se), .si(), .so()); |
---|
| 562 | dff_s #(`IC_IDX_SZ) ldix3_reg(.din (ldindex3_nxt), |
---|
| 563 | .q (ldindex3), |
---|
| 564 | .clk (clk), .se(se), .si(), .so()); |
---|
| 565 | |
---|
| 566 | // Pick dcache index corresponding to current thread |
---|
| 567 | mux4ds #(`IC_IDX_SZ) ldinv_mux(.dout (ldinv_addr_i2), |
---|
| 568 | .in0 (ldindex0), |
---|
| 569 | .in1 (ldindex1), |
---|
| 570 | .in2 (ldindex2), |
---|
| 571 | .in3 (ldindex3), |
---|
| 572 | .sel0 (dcpxthr_i2[0]), |
---|
| 573 | .sel1 (dcpxthr_i2[1]), |
---|
| 574 | .sel2 (dcpxthr_i2[2]), |
---|
| 575 | .sel3 (dcpxthr_i2[3])); |
---|
| 576 | |
---|
| 577 | // Final Mux for Index |
---|
| 578 | assign icvidx_sel_wr_i2 = imissrtn_i2 | ifc_inv_asireq_i2 | |
---|
| 579 | mbist_icache_write | ~ifc_inv_ifqadv_i2; |
---|
| 580 | assign icvidx_sel_ld_i2 = ldinv_i2 & ifc_inv_ifqadv_i2; |
---|
| 581 | assign icvidx_sel_inv_i2 = ~imissrtn_i2 & ~ldinv_i2 & |
---|
| 582 | ~ifc_inv_asireq_i2 & ifc_inv_ifqadv_i2 & |
---|
| 583 | ~mbist_icache_write; |
---|
| 584 | |
---|
| 585 | mux3ds #(`IC_IDX_SZ) icv_idx_mux( |
---|
| 586 | .dout (ifq_icv_wrindex_bf[`IC_IDX_HI:5]), |
---|
| 587 | .in0 (icaddr_i2[`IC_IDX_HI:5]), |
---|
| 588 | .in1 ({inv_addr_i2[`IC_IDX_HI:6], 1'b0}), |
---|
| 589 | .in2 (ldinv_addr_i2[`IC_IDX_HI:5]), |
---|
| 590 | .sel0 (icvidx_sel_wr_i2), |
---|
| 591 | .sel1 (icvidx_sel_inv_i2), |
---|
| 592 | .sel2 (icvidx_sel_ld_i2)); |
---|
| 593 | |
---|
| 594 | sink #(`CPX_WIDTH) s0(.in (ifd_inv_ifqop_i2)); |
---|
| 595 | |
---|
| 596 | |
---|
| 597 | endmodule // sparc_ifu_invctl |
---|