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

Revision 6, 29.7 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_ifqdp.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_ifqdp
24//  Description:       
25//  The IFQ is the icache fill queue.  This communicates between the
26//  IFU and the outside world.  It handles icache misses and
27//  invalidate requests from the crossbar. 
28//
29*/
30
31//FPGA_SYN enables all FPGA related modifications
32`ifdef FPGA_SYN 
33`define FPGA_SYN_CLK_EN
34`define FPGA_SYN_CLK_DFF
35`endif
36
37////////////////////////////////////////////////////////////////////////
38// Global header file includes
39////////////////////////////////////////////////////////////////////////
40
41`include "iop.h"
42`include "ifu.h"
43
44////////////////////////////////////////////////////////////////////////
45// Local header file includes / local defines
46////////////////////////////////////////////////////////////////////////
47
48module sparc_ifu_ifqdp(/*AUTOARG*/
49   // Outputs
50   so, ifu_lsu_pcxpkt_e, ifq_fdp_fill_inst, ifq_erb_asidata_i2, 
51   ifd_inv_ifqop_i2, ifq_icd_index_bf, ifq_icd_wrdata_i2, 
52   ifq_ict_wrtag_f, ifq_erb_wrindex_f, ifq_icd_wrway_bf, 
53   ifd_ifc_milhit_s, ifd_ifc_instoffset0, ifd_ifc_instoffset1, 
54   ifd_ifc_instoffset2, ifd_ifc_instoffset3, ifd_ifc_cpxthr_nxt, 
55   ifd_ifc_cpxreq_nxt, ifd_ifc_cpxreq_i1, ifd_ifc_destid0, 
56   ifd_ifc_destid1, ifd_ifc_destid2, ifd_ifc_destid3, 
57   ifd_ifc_newdestid_s, ifd_ifc_pcxline_d, ifd_ifc_asi_vachklo_i2, 
58   ifd_ifc_cpxvld_i2, ifd_ifc_asiaddr_i2, ifd_ifc_iobpkt_i2, 
59   ifd_ifc_fwd2ic_i2, ifd_ifc_4bpkt_i2, ifd_ifc_cpxnc_i2, 
60   ifd_ifc_cpxce_i2, ifd_ifc_cpxue_i2, ifd_ifc_cpxms_i2, 
61   ifd_ifc_miladdr4_i2, ifd_inv_wrway_i2, 
62   // Inputs
63   rclk, se, si, lsu_ifu_cpxpkt_i1, lsu_ifu_asi_addr, 
64   lsu_ifu_stxa_data, itlb_ifq_paddr_s, fdp_ifq_paddr_f, 
65   ifc_ifd_reqvalid_e, ifc_ifd_filladdr4_i2, ifc_ifd_repway_s, 
66   ifc_ifd_uncached_e, ifc_ifd_thrid_e, ifc_ifd_pcxline_adj_d, 
67   ifc_ifd_errinv_e, ifc_ifd_ldmil_sel_new, ifc_ifd_ld_inq_i1, 
68   ifc_ifd_idx_sel_fwd_i2, ifc_ifd_milreq_sel_d_l, 
69   ifc_ifd_milfill_sel_i2_l, ifc_ifd_finst_sel_l, 
70   ifc_ifd_ifqbyp_sel_fwd_l, ifc_ifd_ifqbyp_sel_inq_l, 
71   ifc_ifd_ifqbyp_sel_asi_l, ifc_ifd_ifqbyp_sel_lsu_l, 
72   ifc_ifd_ifqbyp_en_l, ifc_ifd_addr_sel_bist_i2_l, 
73   ifc_ifd_addr_sel_asi_i2_l, ifc_ifd_addr_sel_old_i2_l, 
74   ifc_ifd_addr_sel_fill_i2_l, mbist_icache_way, mbist_icache_word, 
75   mbist_icache_index
76   );
77
78   input         rclk, 
79           se, 
80           si;
81   
82   input [`CPX_WIDTH-1:0] lsu_ifu_cpxpkt_i1;
83   input [17:0]   lsu_ifu_asi_addr;
84   input [47:0]   lsu_ifu_stxa_data;
85   
86   input [39:10]  itlb_ifq_paddr_s;
87   input [9:2]    fdp_ifq_paddr_f;
88   
89   // from ifqctl
90   input         ifc_ifd_reqvalid_e;
91   input         ifc_ifd_filladdr4_i2;
92   input [1:0]   ifc_ifd_repway_s;
93   input         ifc_ifd_uncached_e;
94   input [1:0]   ifc_ifd_thrid_e;
95   input [4:2]   ifc_ifd_pcxline_adj_d;
96   
97   input         ifc_ifd_errinv_e;
98   
99   // 2:1 mux selects
100   input [3:0]   ifc_ifd_ldmil_sel_new;  // mil load enable
101   
102   input        ifc_ifd_ld_inq_i1;        // ld new cpxreq to in buffer
103   input        ifc_ifd_idx_sel_fwd_i2;
104   
105   // other mux selects
106   input [3:0]  ifc_ifd_milreq_sel_d_l,   // selects outgoing mil_req
107                            ifc_ifd_milfill_sel_i2_l; // selects the mil entry just
108         // returned from the fill
109         // port
110   input [3:0]  ifc_ifd_finst_sel_l;    // address to load to thr IR
111
112   input        ifc_ifd_ifqbyp_sel_fwd_l, // select next input to process
113                            ifc_ifd_ifqbyp_sel_inq_l,
114                            ifc_ifd_ifqbyp_sel_asi_l,
115                            ifc_ifd_ifqbyp_sel_lsu_l;
116         input        ifc_ifd_ifqbyp_en_l;   
117
118   input        ifc_ifd_addr_sel_bist_i2_l,
119                            ifc_ifd_addr_sel_asi_i2_l,
120                ifc_ifd_addr_sel_old_i2_l,
121                            ifc_ifd_addr_sel_fill_i2_l;
122   
123   input [1:0]  mbist_icache_way;
124   input        mbist_icache_word;
125   input [7:0]  mbist_icache_index;
126   
127   output       so;
128   
129   output [51:0] ifu_lsu_pcxpkt_e;
130
131   output [32:0] ifq_fdp_fill_inst;
132   output [47:0] ifq_erb_asidata_i2;
133
134   output [`CPX_WIDTH-1:0] ifd_inv_ifqop_i2;
135
136   output [`IC_IDX_HI:2]  ifq_icd_index_bf;   // index for wr and bist
137   
138   output [135:0]         ifq_icd_wrdata_i2;
139   output [`IC_TAG_SZ:0]  ifq_ict_wrtag_f;      // fill tag
140//   output [`IC_TAG_SZ-1:0] ifq_erb_wrtag_f;      // tag w/o parity
141   output [`IC_IDX_HI:4]   ifq_erb_wrindex_f;
142   output [1:0]            ifq_icd_wrway_bf;     // fill data way
143   
144   output [3:0]           ifd_ifc_milhit_s;     // if an Imiss hits in MIL
145//   output [7:0]           ifd_ifc_mil_repway_s;
146   
147   output [1:0]           ifd_ifc_instoffset0;   // to select inst to TIR
148   output [1:0]           ifd_ifc_instoffset1;   // to select inst to TIR
149   output [1:0]           ifd_ifc_instoffset2;   // to select inst to TIR
150   output [1:0]           ifd_ifc_instoffset3;   // to select inst to TIR
151
152   output [1:0]            ifd_ifc_cpxthr_nxt;
153   output [3:0]            ifd_ifc_cpxreq_nxt;    // cpx reqtype + vbit
154   output [`CPX_RQ_SIZE:0] ifd_ifc_cpxreq_i1;    // cpx reqtype + vbit
155
156   
157   output [2:0]            ifd_ifc_destid0,
158                                       ifd_ifc_destid1,
159                                       ifd_ifc_destid2,
160                                       ifd_ifc_destid3,
161                                       ifd_ifc_newdestid_s;
162
163   output [4:2]            ifd_ifc_pcxline_d;
164
165   output                  ifd_ifc_asi_vachklo_i2;
166                         
167   output                  ifd_ifc_cpxvld_i2;
168   output [3:2]            ifd_ifc_asiaddr_i2;   
169   output                  ifd_ifc_iobpkt_i2;
170   output                  ifd_ifc_fwd2ic_i2;
171   output                  ifd_ifc_4bpkt_i2;
172   output                  ifd_ifc_cpxnc_i2;
173   output                  ifd_ifc_cpxce_i2,
174                                       ifd_ifc_cpxue_i2,
175                           ifd_ifc_cpxms_i2;
176   
177   output [3:0]            ifd_ifc_miladdr4_i2;
178   
179   output [1:0]            ifd_inv_wrway_i2;
180
181   
182         
183   //----------------------------------------------------------------------
184   // Declarations
185   //----------------------------------------------------------------------   
186
187   // local signals
188   wire [39:0]             imiss_paddr_s;
189   wire [9:2]              lcl_paddr_s;
190   
191   wire [42:2]             mil_entry0,         // mil entries
192                                       mil_entry1,
193                                       mil_entry2,
194                                       mil_entry3;
195
196//   wire [42:2]             mil0_in_s,          // inputs to mil
197//                                     mil1_in_s,
198//                                     mil2_in_s,
199//                                     mil3_in_s;
200
201   wire                    tag_par_s,
202                                       tag_par_i2;
203
204   wire [42:2]             newmil_entry_s;
205   
206   wire [42:2]             mil_pcxreq_d,        // outgoing request from mil
207                                       pcxreq_d,            // mil or direct ic or prev req
208                                       pcxreq_e;          // outgoing request to lsu
209
210   wire [42:2]             fill_addr_i2,
211                                       fill_addr_adj,
212                                       icaddr_i2,
213                                       asi_addr_i2,
214                                       bist_addr_i2;
215
216   wire [42:4]             wraddr_f;
217
218
219   wire [`CPX_WIDTH-1:0]   inq_cpxpkt_i1,   // output from inq
220//                                           inq_cpxpkt_nxt,
221                                             stxa_data_pkt,
222                           fwd_data_pkt,
223                                             ifqop_i1,
224                                             ifqop_i2;        // ifq op currently being processed
225
226   wire [3:0]              swc_i2;
227   
228   wire [135:0]            icdata_i2;
229   
230   wire [3:0]              parity_i2,
231                                       par_i2;
232
233   wire [17:0]             asi_va_i2,
234                           asi_va_i1;
235   wire [13:2]             asi_fwd_index;
236   wire                    clk;
237   
238   
239//   wire [`IC_IDX_HI:6]     inv_addr_i2;
240   
241   //
242   // Code start here
243   //
244
245   assign                  clk = rclk;
246   
247   //----------------------------------------------------------------------
248   // Instruction Miss - Fill Request Datapath
249   //----------------------------------------------------------------------
250
251   // new set of flops
252   dff_s #(8) pcs_reg(.din (fdp_ifq_paddr_f[9:2]),
253                    .q   (lcl_paddr_s[9:2]),
254                    .clk (clk), .se(se), .si(), .so());
255                   
256
257   // bits 1:0 are floating
258   assign  imiss_paddr_s = {itlb_ifq_paddr_s[39:10], 
259                            lcl_paddr_s[9:2],
260                            2'b0};
261   
262   // Check for hit in MIL
263   // Should we enable the comps to save power? -- timing problem
264
265   // compare only top 35 bits (bot 5 bits are line offset of 32B line)
266   sparc_ifu_cmp35 milcmp0 (.hit (ifd_ifc_milhit_s[0]),
267                                              .a (imiss_paddr_s[39:5]),
268                                              .b (mil_entry0[39:5]),
269                                              .valid (1'b1)
270                                              );
271   
272   sparc_ifu_cmp35 milcmp1 (.hit (ifd_ifc_milhit_s[1]),
273                                              .a (imiss_paddr_s[39:5]),
274                                              .b (mil_entry1[39:5]),
275                                              .valid (1'b1)
276                                              );
277   
278   sparc_ifu_cmp35 milcmp2 (.hit (ifd_ifc_milhit_s[2]),
279                                              .a (imiss_paddr_s[39:5]),
280                                              .b (mil_entry2[39:5]),
281                                              .valid (1'b1)
282                                              );
283   sparc_ifu_cmp35 milcmp3 (.hit (ifd_ifc_milhit_s[3]),
284                                              .a (imiss_paddr_s[39:5]),
285                                              .b (mil_entry3[39:5]),
286                                              .valid (1'b1)
287                                              );
288
289   // Send replacement way to ctl logic
290//   assign  ifd_ifc_mil_repway_s =  {mil_entry3[41:40],
291//                                        mil_entry2[41:40],
292//                                        mil_entry1[41:40],
293//                                        mil_entry0[41:40]};
294
295
296   // calculate tag parity
297   sparc_ifu_par32 tag_par(.in  ({{`ICT_FILL_BITS{1'b0}}, 
298                                  imiss_paddr_s[`IC_TAG_HI:`IC_TAG_LO]}),
299                                             .out (tag_par_s));
300
301
302   // Missed Instruction List
303   // 43    - NOT cacheable
304   // 42    - tag parity
305   // 41:40 - repl way
306   // 39:0  - paddr
307
308   // Prepare Missed Instruction List entry
309   assign  newmil_entry_s = {tag_par_s,
310                                               ifc_ifd_repway_s,                           
311                                               imiss_paddr_s[39:2]};
312
313   // ldmil_sel is thr_s[3:0] & imiss_s
314//   dp_mux2es  #(41)    milin_mux0(.dout (mil0_in_s),
315//                                                        .in0  (mil_entry0),
316//                                                        .in1  (newmil_entry_s),
317//                                                        .sel  (ifc_ifd_ldmil_sel_new[0]));
318//   dp_mux2es  #(41)    milin_mux1(.dout (mil1_in_s),
319//                                                      .in0  (mil_entry1),
320//                                                      .in1  (newmil_entry_s),
321//                                                      .sel  (ifc_ifd_ldmil_sel_new[1]));
322//   dp_mux2es  #(41)    milin_mux2(.dout (mil2_in_s),
323//                                                      .in0  (mil_entry2),
324//                                                      .in1  (newmil_entry_s),
325//                                                      .sel  (ifc_ifd_ldmil_sel_new[2]));
326//   dp_mux2es  #(41)    milin_mux3(.dout (mil3_in_s),
327//                                                      .in0  (mil_entry3),
328//                                                      .in1  (newmil_entry_s),
329//                                                      .sel  (ifc_ifd_ldmil_sel_new[3]));
330
331   wire    clk_mil0;
332`ifdef FPGA_SYN_CLK_EN
333`else
334   bw_u1_ckenbuf_6x  ckenmil0(.rclk (rclk),
335                              .clk  (clk_mil0),
336                              .en_l (~ifc_ifd_ldmil_sel_new[0]),
337                              .tm_l (~se));
338`endif
339   wire    clk_mil1;
340`ifdef FPGA_SYN_CLK_EN
341`else
342   bw_u1_ckenbuf_6x  ckenmil1(.rclk (rclk),
343                              .clk  (clk_mil1),
344                              .en_l (~ifc_ifd_ldmil_sel_new[1]),
345                              .tm_l (~se));
346`endif
347   wire    clk_mil2;
348`ifdef FPGA_SYN_CLK_EN
349`else
350   bw_u1_ckenbuf_6x  ckenmil2(.rclk (rclk),
351                              .clk  (clk_mil2),
352                              .en_l (~ifc_ifd_ldmil_sel_new[2]),
353                              .tm_l (~se));
354`endif
355   wire    clk_mil3;
356`ifdef FPGA_SYN_CLK_EN
357`else
358   bw_u1_ckenbuf_6x  ckenmil3(.rclk (rclk),
359                              .clk  (clk_mil3),
360                              .en_l (~ifc_ifd_ldmil_sel_new[3]),
361                              .tm_l (~se));
362`endif
363   
364
365`ifdef FPGA_SYN_CLK_DFF
366   dffe_s #(41)   mil0(.din  (newmil_entry_s), 
367                                .en (~(~ifc_ifd_ldmil_sel_new[0])), .clk(rclk), 
368                                .q    (mil_entry0), 
369                                .se   (se), .si(), .so());
370`else
371   dff_s #(41)   mil0(.din  (newmil_entry_s), 
372                                .clk  (clk_mil0), 
373                                .q    (mil_entry0), 
374                                .se   (se), .si(), .so());
375`endif
376
377`ifdef FPGA_SYN_CLK_DFF
378   dffe_s #(41)   mil1(.din (newmil_entry_s), 
379                                .en (~(~ifc_ifd_ldmil_sel_new[1])), .clk(rclk), 
380                                .q   (mil_entry1), 
381                                .se  (se), .si(), .so());
382`else
383   dff_s #(41)   mil1(.din (newmil_entry_s), 
384                                .clk (clk_mil1), 
385                                .q   (mil_entry1), 
386                                .se  (se), .si(), .so());
387`endif
388
389`ifdef FPGA_SYN_CLK_DFF
390   dffe_s #(41)   mil2(.din (newmil_entry_s), 
391                                .en (~(~ifc_ifd_ldmil_sel_new[2])), .clk(rclk), 
392                                .q   (mil_entry2), 
393                                .se  (se), .si(), .so());
394`else
395   dff_s #(41)   mil2(.din (newmil_entry_s), 
396                                .clk (clk_mil2), 
397                                .q   (mil_entry2), 
398                                .se  (se), .si(), .so());
399`endif
400
401`ifdef FPGA_SYN_CLK_DFF
402   dffe_s #(41)   mil3(.din (newmil_entry_s), 
403                                .en (~(~ifc_ifd_ldmil_sel_new[3])), .clk(rclk), 
404                                .q   (mil_entry3), 
405                                .se  (se), .si(), .so());
406`else
407   dff_s #(41)   mil3(.din (newmil_entry_s), 
408                                .clk (clk_mil3), 
409                                .q   (mil_entry3), 
410                                .se  (se), .si(), .so());
411`endif
412
413   assign  ifd_ifc_newdestid_s = {imiss_paddr_s[39], 
414                                                          imiss_paddr_s[`BANK_ID_HI:`BANK_ID_LO]};
415   assign  ifd_ifc_destid0 = {mil_entry0[39], 
416                                                mil_entry0[`BANK_ID_HI:`BANK_ID_LO]};
417   assign  ifd_ifc_destid1 = {mil_entry1[39], 
418                                                mil_entry1[`BANK_ID_HI:`BANK_ID_LO]};
419   assign  ifd_ifc_destid2 = {mil_entry2[39], 
420                                                mil_entry2[`BANK_ID_HI:`BANK_ID_LO]};
421   assign  ifd_ifc_destid3 = {mil_entry3[39], 
422                                                mil_entry3[`BANK_ID_HI:`BANK_ID_LO]};
423
424   assign  ifd_ifc_instoffset0 = mil_entry0[3:2];
425   assign  ifd_ifc_instoffset1 = mil_entry1[3:2];
426   assign  ifd_ifc_instoffset2 = mil_entry2[3:2];
427   assign  ifd_ifc_instoffset3 = mil_entry3[3:2];
428   
429   
430   // MIL Request Out mux
431   dp_mux4ds  #(41)  milreq_mux (.dout (mil_pcxreq_d),
432                                                 .in0  ({mil_entry0[42:2]}),
433                                                 .in1  ({mil_entry1[42:2]}),
434                                                 .in2  ({mil_entry2[42:2]}),
435                                                 .in3  ({mil_entry3[42:2]}),
436                                                 .sel0_l  (ifc_ifd_milreq_sel_d_l[0]),
437                                                 .sel1_l  (ifc_ifd_milreq_sel_d_l[1]),
438                                                 .sel2_l  (ifc_ifd_milreq_sel_d_l[2]),
439                                                 .sel3_l  (ifc_ifd_milreq_sel_d_l[3]));
440   
441   // Next PCX Request Mux
442//   dp_mux3ds  #(44)  nxtpcx_mux (.dout  (pcxreq_d),
443//                                               .in0   (mil_pcxreq_d),
444//                                               .in1   (44'bx),
445//                                               .in2   (pcxreq_e),
446//                                               .sel0_l  (ifc_ifd_nxtpcx_sel_new_d_l),
447//                                               .sel1_l  (ifc_ifd_nxtpcx_sel_err_d_l),
448//                                               .sel2_l  (ifc_ifd_nxtpcx_sel_prev_d_l));
449
450
451   // TBD: If destid == any L2 bank, need to zero out bit 4 for Rams
452   //    -- done
453   assign  ifd_ifc_pcxline_d[4:2] = mil_pcxreq_d[4:2];
454   
455   assign  pcxreq_d[42:5] = mil_pcxreq_d[42:5];
456   assign  pcxreq_d[4:2] = ifc_ifd_pcxline_adj_d[4:2];
457//   assign  pcxreq_d[1:0] = mil_pcxreq_d[1:0];  // dont need this
458
459   dff_s #(41) pcxreq_reg (.din  (pcxreq_d),
460                                            .clk  (clk),
461                                            .q    (pcxreq_e),
462                                            .se   (se), .si(), .so());
463
464// CHANGE to regular dff   
465//   dffe #(44) pcxreq_reg (.din  (pcxreq_d),
466//                                          .clk  (clk),
467//                                          .q    (pcxreq_e),
468//                          .en   (ifc_ifd_nxtpcx_sel_new_d),
469//                                          .se   (se), .si(), .so());
470   
471   // PCX Req Reg -- req type is 5 bits
472   assign   ifu_lsu_pcxpkt_e = {ifc_ifd_reqvalid_e,   // 51    - valid
473                                                  ifc_ifd_errinv_e,     // 50 - inv all ways
474                                ifc_ifd_uncached_e,   // 49 - not cacheable
475                                                  {`IMISS_RQ},          // 48:44 - req type
476                                                  pcxreq_e[41:40],      // 43:42 - rep way
477                                                  ifc_ifd_thrid_e[1:0], // 41:40 - thrid
478                                                  pcxreq_e[39:2],       // 39:2  - word address
479                                                  2'b0};                // force to zero
480   
481
482   //----------------------------------------------------------------------
483   // Fill Return Address
484   //----------------------------------------------------------------------
485
486   // MIL Fill Return Mux
487   dp_mux4ds  #(41)  milfill_mux(.dout (fill_addr_i2),
488                                                 .in0 ( mil_entry0),
489                                                 .in1 ( mil_entry1),
490                                                 .in2 ( mil_entry2),
491                                                 .in3 ( mil_entry3),
492                                                 .sel0_l (ifc_ifd_milfill_sel_i2_l[0]),
493                                                 .sel1_l (ifc_ifd_milfill_sel_i2_l[1]),
494                                                 .sel2_l (ifc_ifd_milfill_sel_i2_l[2]),
495                                                 .sel3_l (ifc_ifd_milfill_sel_i2_l[3]));
496
497   assign   ifd_ifc_miladdr4_i2[3:0]  = {mil_entry3[4],
498                                         mil_entry2[4],
499                                         mil_entry1[4],
500                                         mil_entry0[4]};
501   
502   assign   ifd_ifc_iobpkt_i2 = fill_addr_i2[39];
503   assign   fill_addr_adj = {fill_addr_i2[42:5], 
504                                               ifc_ifd_filladdr4_i2,
505                                               fill_addr_i2[3:2]};
506   // determine if this is cacheable in I$
507   // moved to ifqctl
508//   assign   ifd_ifc_uncached_i2 = fill_addr_i2[43];
509
510   // merged with addren mux to save some timing
511   dp_mux4ds #(41) icadr_mux(.dout (icaddr_i2),
512                                               .in0  (fill_addr_adj),
513                                               .in1  (asi_addr_i2),
514                                               .in2  (bist_addr_i2),
515                             .in3  ({wraddr_f[42:4], 2'b0}),
516                                               .sel0_l (ifc_ifd_addr_sel_fill_i2_l),
517                                               .sel1_l (ifc_ifd_addr_sel_asi_i2_l),
518                                               .sel2_l (ifc_ifd_addr_sel_bist_i2_l),
519                             .sel3_l (ifc_ifd_addr_sel_old_i2_l));
520   
521   // way, 32B line sel
522   assign ifd_inv_wrway_i2 =  icaddr_i2[41:40];
523
524//   dp_mux2es  #(39)  addren_mux(.dout (wraddr_i2),
525//                                              .in0  (wraddr_f),
526//                                              .in1  (icaddr_i2[42:4]),
527//                                              .sel  (ifc_ifd_ifqadv_i2));
528
529   
530   dff_s #(39) wraddr_reg(.din  (icaddr_i2[42:4]),
531                                    .clk  (clk),
532                                    .q    (wraddr_f[42:4]),
533                                    .se   (se), .si(), .so());
534
535   // tag = parity bit + `IC_TAG_SZ bits of address
536   assign  ifq_erb_wrindex_f = wraddr_f[`IC_IDX_HI:4];
537   assign  ifq_ict_wrtag_f = {wraddr_f[42], wraddr_f[`IC_TAG_HI:`IC_TAG_LO]};
538
539   assign  ifq_icd_index_bf = icaddr_i2[`IC_IDX_HI:2];
540   assign  ifq_icd_wrway_bf = icaddr_i2[41:40];
541
542   //----------------------------------------------------------------------
543   // Fill Return Data
544   //----------------------------------------------------------------------
545   // IFQ-IBUF
546   // inq is the same size as the cpx_width
547   // inq is replaced with a single flop, ibuf
548
549   // ibuf enable mux
550//   dp_mux2es  #(`CPX_WIDTH)  ifqen_mux(.dout (inq_cpxpkt_nxt),
551//                                                           .in0 (inq_cpxpkt_i1),
552//                                                           .in1 (lsu_ifu_cpxpkt_i1),
553//                                                           .sel (ifc_ifd_ld_inq_i1));
554
555   wire    clk_ibuf1;
556`ifdef FPGA_SYN_CLK_EN
557`else
558   bw_u1_ckenbuf_6x  ckenibuf(.rclk (rclk),
559                              .clk  (clk_ibuf1),
560                              .en_l (~ifc_ifd_ld_inq_i1),
561                              .tm_l (~se));
562`endif
563                             
564`ifdef FPGA_SYN_CLK_DFF
565   dffe_s #(`CPX_WIDTH) ibuf(.din (lsu_ifu_cpxpkt_i1),
566                                          .q   (inq_cpxpkt_i1),
567                                          .en (~(~ifc_ifd_ld_inq_i1)), .clk(rclk),
568                                          .se  (se), .si(), .so());
569`else
570   dff_s #(`CPX_WIDTH) ibuf(.din (lsu_ifu_cpxpkt_i1),
571                                          .q   (inq_cpxpkt_i1),
572                                          .clk (clk_ibuf1),
573                                          .se  (se), .si(), .so());
574`endif
575
576   assign  ifd_ifc_cpxreq_i1 = {inq_cpxpkt_i1[`CPX_VLD], 
577                                                  inq_cpxpkt_i1[`CPX_REQFIELD]};
578
579   // ifq operand bypass mux
580   // fill pkt is 128d+2w+2t+3iw+1v+1nc+4r = 140
581   dp_mux4ds  #(`CPX_WIDTH)  ifq_bypmux(.dout (ifqop_i1),
582                                                              .in0 (fwd_data_pkt), 
583                                                              .in1 (inq_cpxpkt_i1),
584                                                              .in2 (stxa_data_pkt),
585                                                              .in3 (lsu_ifu_cpxpkt_i1),
586                                                              .sel0_l (ifc_ifd_ifqbyp_sel_fwd_l),
587                                                              .sel1_l (ifc_ifd_ifqbyp_sel_inq_l),
588                                                              .sel2_l (ifc_ifd_ifqbyp_sel_asi_l),
589                                                              .sel3_l (ifc_ifd_ifqbyp_sel_lsu_l));
590   
591   wire    clk_ifqop;
592`ifdef FPGA_SYN_CLK_EN
593`else
594   bw_u1_ckenbuf_6x  ckenifop(.rclk (rclk),
595                              .clk  (clk_ifqop),
596                              .en_l (ifc_ifd_ifqbyp_en_l),
597                              .tm_l (~se));
598`endif
599   
600`ifdef FPGA_SYN_CLK_DFF
601   dffe_s #(`CPX_WIDTH)  ifqop_reg(.din (ifqop_i1), 
602                                                .q   (ifqop_i2), 
603                                                .en (~(ifc_ifd_ifqbyp_en_l)), .clk(rclk), 
604                                                .se  (se), .si(), .so());
605`else
606   dff_s #(`CPX_WIDTH)  ifqop_reg(.din (ifqop_i1), 
607                                                .q   (ifqop_i2), 
608                                                .clk (clk_ifqop), 
609                                                .se  (se), .si(), .so());
610`endif
611   assign  ifd_inv_ifqop_i2 = ifqop_i2;
612   
613   // switch condition pre decode
614   sparc_ifu_swpla  swpla0(.in  (ifqop_i2[31:0]),
615                                             .out (swc_i2[0]));
616   sparc_ifu_swpla  swpla1(.in  (ifqop_i2[63:32]),
617                                             .out (swc_i2[1]));
618   sparc_ifu_swpla  swpla2(.in  (ifqop_i2[95:64]),
619                                             .out (swc_i2[2]));
620   sparc_ifu_swpla  swpla3(.in  (ifqop_i2[127:96]),
621                                             .out (swc_i2[3]));
622
623   // Add Parity to each inst.
624   sparc_ifu_par32 par0(.in  (ifqop_i2[31:0]),
625                                          .out (par_i2[0]));
626   sparc_ifu_par32 par1(.in  (ifqop_i2[63:32]),
627                                          .out (par_i2[1]));
628   sparc_ifu_par32 par2(.in  (ifqop_i2[95:64]),
629                                          .out (par_i2[2]));
630   sparc_ifu_par32 par3(.in  (ifqop_i2[127:96]),
631                                          .out (par_i2[3]));
632
633   // add 8 xor gates in the dp
634   //   assign parity_i2 = par_i2 ^ swc_i2 ^ {4{ifc_ifd_insert_pe}};
635   //   assign tag_par_i2 = par_i2[0] ^ ifc_ifd_insert_pe;
636
637   // Make the par32 cell above, par33 and include cpxue_i2
638   assign   parity_i2 = par_i2 ^ swc_i2 ^ {4{ifd_ifc_cpxue_i2}};
639   assign   tag_par_i2 = par_i2[0] ^ ifd_ifc_cpxue_i2;
640   
641   // parity, swc, inst[31:0]
642   assign   icdata_i2 = {parity_i2[3], ifqop_i2[127:96], swc_i2[3],
643                                     parity_i2[2], ifqop_i2[95:64],  swc_i2[2],
644                                     parity_i2[1], ifqop_i2[63:32],  swc_i2[1],
645                                     parity_i2[0], ifqop_i2[31:0],   swc_i2[0]};
646
647   // write data to icache
648   assign ifq_icd_wrdata_i2 = icdata_i2;
649
650
651   // very critical
652   assign ifd_ifc_cpxreq_nxt   = ifqop_i1[`CPX_REQFIELD];
653   assign ifd_ifc_cpxthr_nxt   = ifqop_i1[`CPX_THRFIELD];
654
655   assign ifd_ifc_cpxvld_i2   = ifqop_i2[`CPX_VLD];
656   assign ifd_ifc_4bpkt_i2    = ifqop_i2[`CPX_IF4B];
657   assign ifd_ifc_cpxce_i2    = ifqop_i2[`CPX_ERR_LO];
658   assign ifd_ifc_cpxue_i2    = ifqop_i2[(`CPX_ERR_LO + 1)];
659   assign ifd_ifc_cpxms_i2    = ifqop_i2[(`CPX_ERR_LO + 2)];
660   assign ifd_ifc_cpxnc_i2    = ifqop_i2[`CPX_NC];
661   assign ifd_ifc_fwd2ic_i2   = ifqop_i2[103];
662
663   // instr sel mux to write to thread inst regsiter in S stage
664   // instr is always BIG ENDIAN
665   dp_mux4ds  #(33)  fillinst_mux(.dout (ifq_fdp_fill_inst),
666                                                        .in0 (icdata_i2[134:102]),
667                                                        .in1 (icdata_i2[100:68]),
668                                                        .in2 (icdata_i2[66:34]),
669                                                        .in3 (icdata_i2[32:0]),
670                                                        .sel0_l (ifc_ifd_finst_sel_l[0]),
671                                                        .sel1_l (ifc_ifd_finst_sel_l[1]),
672                                                        .sel2_l (ifc_ifd_finst_sel_l[2]),
673                                                        .sel3_l (ifc_ifd_finst_sel_l[3]));
674
675   // synopsys translate_off
676//`ifdef DEFINE_0IN
677//`else
678//   always @ (ifq_fdp_fill_inst or ifd_ifc_cpxreq_i2)
679//     if (((^ifq_fdp_fill_inst[32:0]) == 1'bx) && (ifd_ifc_cpxreq_i2 == `CPX_IFILLPKT))
680//       begin
681//          $display("ifqdp.v: Imiss Return val = %h\n", ifqop_i2);
682//          $error("IFQCPX", "Error: X's detected in Imiss Return Inst %h",
683//                 ifq_fdp_fill_inst[31:0]);
684//       end
685//`endif
686   // synopsys translate_on
687   
688   
689   // TBD: 1. inv way in fill pkt -- DONE
690   //      2. inv packet -- DONE
691   //      3. DFT pkt from TAP -- NO NEED
692   //      4. Ld pkt to invalidate i$  -- DONE
693
694   //----------------------------------------------------------------------
695   // ASI Access
696   //----------------------------------------------------------------------
697   // mux stxa pkt into the cpx
698   assign  stxa_data_pkt[`CPX_VLD] = 1'b0;
699   // vbits and parity are muxed into the cpxreq
700   assign  stxa_data_pkt[`CPX_REQFIELD] = {1'b1, lsu_ifu_stxa_data[34:32]}; 
701//   assign  stxa_data_pkt[`CPX_THRFIELD] = lsu_ifu_asi_thrid[1:0];
702   assign  stxa_data_pkt[`CPX_THRFIELD] = 2'b0;   
703   // use parity to insert error in icache inst or tag
704   assign  stxa_data_pkt[(`CPX_ERR_LO + 1)] = lsu_ifu_stxa_data[32];   
705   assign  stxa_data_pkt[127:0] = {4{lsu_ifu_stxa_data[31:0]}};
706
707   // other bits need to be tied off
708   assign  stxa_data_pkt[133:128] = 6'b0;   
709   assign  stxa_data_pkt[137:136] = 2'b0;   
710   assign  stxa_data_pkt[139] = 1'b0;
711
712   // format fwd data pkt in a similar way
713   assign  fwd_data_pkt[`CPX_VLD:(`CPX_ERR_LO + 2)] = ifqop_i2[`CPX_VLD:(`CPX_ERR_LO + 2)];
714   assign  fwd_data_pkt[(`CPX_ERR_LO + 1)] = ifqop_i2[32];   
715   assign  fwd_data_pkt[`CPX_ERR_LO:128] = ifqop_i2[`CPX_ERR_LO:128];
716   assign  fwd_data_pkt[127:0] = {4{ifqop_i2[31:0]}};
717   
718
719   
720   dff_s #(16) stxa_ff(.din (lsu_ifu_stxa_data[47:32]),
721                                 .q   (ifq_erb_asidata_i2[47:32]), 
722                                 .clk (clk), .se(se), .si(), .so());
723   assign  ifq_erb_asidata_i2[31:0] = ifqop_i2[31:0];
724
725   // va[63:32] is truncated
726   // In this architecture we only need va[17:0]
727   // rest of the bits ar ehere only for the address range check
728   // 12 new muxes (10 for addr, 2 for way)
729   // CHANGE: this mux has been moved before the asi_addr_reg, rather
730   // than after.
731   // Use mux flop soffm2?
732   dp_mux2es #(12) asifwd_mx(.dout (asi_fwd_index[13:2]),
733                             .in0  ({lsu_ifu_asi_addr[17:16],   // asi way
734                                     lsu_ifu_asi_addr[12:3]}),  // asi addr
735                             .in1  ({ifqop_i2[81:80],    // fwd rq way
736                                     ifqop_i2[76:67]}),  // fwd rq addr
737                             .sel  (ifc_ifd_idx_sel_fwd_i2));
738
739   assign asi_va_i1 = {asi_fwd_index[13:12],
740                       lsu_ifu_asi_addr[15:13],
741                       asi_fwd_index[11:2],
742                       lsu_ifu_asi_addr[2:0]};
743   
744   dff_s #(18) asi_addr_reg(.din (asi_va_i1[17:0]),  // 15:13 is not used
745                                            .q   (asi_va_i2[17:0]),
746                                            .clk (clk),
747                                            .se  (se), .si(), .so());
748
749   // 16b zero cmp: leave out bit 3!! (imask is 0x8)
750   assign  ifd_ifc_asi_vachklo_i2 = (|asi_va_i2[16:4]) | (|asi_va_i2[2:0]);
751
752   // mux in ifqop and asi_va_i2 to create new asi va?
753   // asi va is shifted by 1 bit to look like 64b op
754   assign    ifd_ifc_asiaddr_i2[3:2] = asi_va_i2[4:3];
755
756   assign    asi_addr_i2 = {tag_par_i2,           // tag parity 42
757                                              asi_va_i2[17:16],     // way 41:40
758                                              ifqop_i2[27:0],       // tag 39:12
759                                              asi_va_i2[12:3]       // index 11:2
760                            };                 
761
762   // bist has to go to icache in the same cycle
763   // cannot flop it
764   assign    bist_addr_i2 = {1'b0,                    // par
765                                               mbist_icache_way[1:0],   // way 41:40
766                                               28'b0,                   // tag 39:12
767                                               mbist_icache_index[7:0], // index 11:4
768                             mbist_icache_word,       // 3
769                                               1'b0
770                                               };
771
772   // floating signals
773   sink #(2) s0(.in (imiss_paddr_s[1:0]));
774   sink s1(.in (pcxreq_e[42]));
775   sink s2(.in (fill_addr_i2[4]));
776   
777   
778endmodule // sparc_ifu_ifqdp
779
780
781
Note: See TracBrowser for help on using the repository browser.