source: XOpenSparcT1/trunk/T1-CPU/ifu/sparc_ifu_invctl.v @ 6

Revision 6, 23.3 KB checked in by pntsvt00, 13 years ago (diff)

versione iniziale opensparc

Line 
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
36module 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
597endmodule // sparc_ifu_invctl
Note: See TracBrowser for help on using the repository browser.