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