1 |
2 |
dmitryr |
// ========== 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
|