1 | // ========== Copyright Header Begin ========================================== |
---|
2 | // |
---|
3 | // OpenSPARC T1 Processor File: sparc_ifu_fcl.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_fcl |
---|
24 | // Description: |
---|
25 | // The FCL is the fetch control logic. It controls the PC datapath |
---|
26 | // and the fetch/next instruction datapath. It also manages access |
---|
27 | // to the icache data, tags, vbits and to the tlb. |
---|
28 | // The FCL starts fetching from the reset PC upon reset. It is up to |
---|
29 | // the DTU to specify which thread to fetch from. Only T0 is set to |
---|
30 | // the reset PC. If the decode unit specifies any other thread, it |
---|
31 | // will fetch from an indeterminate address. |
---|
32 | // The fetch block automatically stalls the machine when an Imiss is |
---|
33 | // detected and there is no thread to switch to. |
---|
34 | // |
---|
35 | */ |
---|
36 | //////////////////////////////////////////////////////////////////////// |
---|
37 | // Global header file includes |
---|
38 | //////////////////////////////////////////////////////////////////////// |
---|
39 | |
---|
40 | `include "ifu.h" |
---|
41 | |
---|
42 | |
---|
43 | module sparc_ifu_fcl(/*AUTOARG*/ |
---|
44 | // Outputs |
---|
45 | fcl_icd_rdreq_bf, fcl_icv_rdreq_bf, fcl_icd_wrreq_bf, |
---|
46 | fcl_ict_wrreq_bf, fcl_icv_wrreq_bf, fcl_icd_index_sel_ifq_bf, |
---|
47 | fcl_ifq_grant_bf, fcl_ifq_icmiss_s1, fcl_ifq_rdreq_s1, |
---|
48 | fcl_ifq_icache_en_s_l, fcl_ifq_thr_s1, fcl_ifq_canthr, |
---|
49 | fcl_itlb_cam_vld_bf, fcl_itlb_cam_bypass_bf, fcl_itlb_addr_mask_l, |
---|
50 | fcl_itlb_cam_real_bf, fcl_itlb_cam_pid_bf, fcl_itlb_wr_vld_bf, |
---|
51 | fcl_itlb_dmp_vld_bf, fcl_itlb_dmp_all_bf, fcl_itlb_tag_rd_vld_bf, |
---|
52 | fcl_itlb_invall_f_l, fcl_itlb_data_rd_vld_bf, fcl_erb_ievld_s1, |
---|
53 | fcl_erb_tevld_s1, fcl_erb_immuevld_s1, ifu_lsu_thrid_s, |
---|
54 | fcl_erb_asi_tid_f, fcl_erb_clear_iferr, fcl_erb_itlbrd_vld_s, |
---|
55 | fcl_erb_itlbrd_data_s, fcl_dec_dslot_s, fcl_dtu_inst_vld_e, |
---|
56 | fcl_dtu_intr_vld_e, fcl_dtu_inst_vld_d, fcl_dtu_ely_inst_vld_d, |
---|
57 | fcl_dec_intr_vld_d, fcl_erb_inst_issue_d, fcl_erb_inst_vld_d1, |
---|
58 | ifu_tlu_inst_vld_m, ifu_exu_inst_vld_e, ifu_exu_inst_vld_w, |
---|
59 | ifu_spu_inst_vld_w, ifu_tlu_inst_vld_w, ifu_tlu_flush_w, |
---|
60 | ifu_tlu_flush_m, fcl_swl_int_activate_i3, fcl_swl_flush_wake_w, |
---|
61 | fcl_swl_flush_w, fcl_dcl_regz_e, ifu_tlu_thrid_e, ifu_tlu_thrid_d, |
---|
62 | ifu_tlu_immu_miss_m, ifu_tlu_priv_violtn_m, ifu_tlu_icmiss_e, |
---|
63 | ifu_tlu_ttype_vld_m, ifu_exu_ttype_vld_m, ifu_mmu_trap_m, |
---|
64 | ifu_tlu_trap_m, ifu_tlu_ttype_m, ifu_tlu_hwint_m, |
---|
65 | ifu_tlu_sftint_m, ifu_tlu_rstint_m, fcl_dtu_rst_thr_w, |
---|
66 | fcl_dtu_resum_thr_w, ifu_tlu_itlb_done, ifu_spu_trap_ack, |
---|
67 | ifu_exu_tid_s2, ifu_exu_ren1_s, ifu_exu_ren2_s, ifu_exu_ren3_s, |
---|
68 | ifu_exu_disable_ce_e, fcl_dtu_sync_intr_d, fcl_dtu_tlzero_d, |
---|
69 | fcl_dtu_privmode_d, fcl_dtu_hprivmode_d, fcl_dtu_hprivmode_w2, |
---|
70 | fcl_dtu_nuke_thr_w, fcl_swl_swout_f, fcl_dtu_stall_bf, |
---|
71 | fcl_swl_swcvld_s, fcl_dtu_thr_f, fcl_imd_oddwin_d, |
---|
72 | fcl_fdp_oddwin_s, fcl_fdp_pcoor_vec_f, fcl_fdp_pcoor_f, |
---|
73 | fcl_fdp_mask32b_f, fcl_fdp_addr_mask_d, fcl_fdp_tctxt_sel_prim, |
---|
74 | fcl_fdp_usenir_sel_nir_s1, fcl_fdp_rbinst_sel_inste_s, |
---|
75 | fcl_fdp_thrtnpc_sel_tnpc_l, fcl_fdp_thrtnpc_sel_npcw_l, |
---|
76 | fcl_fdp_thrtnpc_sel_pcf_l, fcl_fdp_thrtnpc_sel_old_l, |
---|
77 | fcl_fdp_thr_s1_l, fcl_fdp_next_thr_bf_l, fcl_fdp_next_ctxt_bf_l, |
---|
78 | fcl_fdp_nirthr_s1_l, fcl_fdp_thr_s2_l, |
---|
79 | fcl_fdp_tpcbf_sel_pcp4_bf_l, fcl_fdp_tpcbf_sel_brpc_bf_l, |
---|
80 | fcl_fdp_tpcbf_sel_trap_bf_l, fcl_fdp_tpcbf_sel_old_bf_l, |
---|
81 | fcl_fdp_pcbf_sel_nosw_bf_l, fcl_fdp_pcbf_sel_swpc_bf_l, |
---|
82 | fcl_fdp_pcbf_sel_br_bf_l, fcl_fdp_trrbpc_sel_trap_bf_l, |
---|
83 | fcl_fdp_trrbpc_sel_rb_bf_l, fcl_fdp_trrbpc_sel_err_bf_l, |
---|
84 | fcl_fdp_trrbpc_sel_pcs_bf_l, fcl_fdp_noswpc_sel_tnpc_l_bf, |
---|
85 | fcl_fdp_noswpc_sel_old_l_bf, fcl_fdp_noswpc_sel_inc_l_bf, |
---|
86 | fcl_fdp_nextpcs_sel_pce_f_l, fcl_fdp_nextpcs_sel_pcd_f_l, |
---|
87 | fcl_fdp_nextpcs_sel_pcs_f_l, fcl_fdp_nextpcs_sel_pcf_f_l, |
---|
88 | fcl_fdp_inst_sel_curr_s_l, fcl_fdp_inst_sel_switch_s_l, |
---|
89 | fcl_fdp_inst_sel_nir_s_l, fcl_fdp_inst_sel_nop_s_l, |
---|
90 | fcl_fdp_tinst_sel_curr_s_l, fcl_fdp_tinst_sel_rb_s_l, |
---|
91 | fcl_fdp_tinst_sel_old_s_l, fcl_fdp_tinst_sel_ifq_s_l, |
---|
92 | fcl_fdp_dmpthr_l, fcl_fdp_ctxt_sel_dmp_bf_l, |
---|
93 | fcl_fdp_ctxt_sel_sw_bf_l, fcl_fdp_ctxt_sel_curr_bf_l, |
---|
94 | fcl_fdp_rdsr_sel_pc_e_l, fcl_fdp_rdsr_sel_thr_e_l, |
---|
95 | fcl_fdp_rdsr_sel_ver_e_l, so, ifu_reset_l, |
---|
96 | // Inputs |
---|
97 | rclk, grst_l, arst_l, se, sehold, si, rst_tri_en, |
---|
98 | tlu_ifu_flush_pipe_w, exu_ifu_va_oor_m, exu_ifu_oddwin_s, |
---|
99 | spu_ifu_ttype_tid_w2, spu_ifu_ttype_vld_w2, spu_ifu_ttype_w2, |
---|
100 | erb_fcl_spu_uetrap, exu_ifu_regz_e, dcl_fcl_bcregz0_e, |
---|
101 | dcl_fcl_bcregz1_e, dtu_fcl_rollback_g, dtu_fcl_retract_d, |
---|
102 | dtu_fcl_br_inst_d, dtu_fcl_sir_inst_e, dtu_fcl_privop_e, |
---|
103 | dtu_fcl_fpdis_e, dtu_fcl_imask_hit_e, dtu_fcl_illinst_e, |
---|
104 | dtu_fcl_thr_active, dec_fcl_rdsr_sel_pc_d, dec_fcl_rdsr_sel_thr_d, |
---|
105 | ifq_fcl_wrreq_bf, ifq_fcl_icd_wrreq_bf, ifq_fcl_ictv_wrreq_bf, |
---|
106 | ifq_fcl_rdreq_bf, ifq_fcl_asi_tid_bf, ifq_fcl_asird_bf, |
---|
107 | ifq_fcl_invreq_bf, erb_fcl_itlb_ce_d1, erb_dtu_ifeterr_d1, |
---|
108 | erb_fcl_ifet_uevec_d1, erb_fcl_ue_trapvec, erb_fcl_ce_trapvec, |
---|
109 | dtu_fcl_nextthr_bf, dtu_fcl_ntr_s, dtu_fcl_running_s, |
---|
110 | dtu_fcl_flush_sonly_e, fdp_fcl_swc_s2, fdp_fcl_va2_bf, |
---|
111 | itlb_fcl_tlbmiss_f_l, itlb_fcl_priv_s1, itlb_fcl_cp_s1, |
---|
112 | itlb_fcl_imiss_s_l, fdp_fcl_pc_oor_vec_f, fdp_fcl_pc_oor_e, |
---|
113 | fdp_fcl_op_s, fdp_fcl_op3_s, fdp_fcl_ibit_s, lsu_ifu_stallreq, |
---|
114 | ffu_ifu_stallreq, ifq_fcl_stallreq, dtu_inst_anull_e, |
---|
115 | ifq_fcl_fill_thr, ifq_fcl_flush_sonly_e, tlu_ifu_trap_tid_w1, |
---|
116 | tlu_ifu_trappc_vld_w1, tlu_ifu_trapnpc_vld_w1, |
---|
117 | tlu_lsu_pstate_priv, tlu_lsu_pstate_am, tlu_hpstate_priv, |
---|
118 | tlu_lsu_redmode, tlu_hpstate_enb, lsu_ifu_addr_real_l, |
---|
119 | lsu_pid_state0, lsu_pid_state1, lsu_pid_state2, lsu_pid_state3, |
---|
120 | lsu_ifu_icache_en, lsu_ifu_dc_parity_error_w2, lsu_ifu_t0_tlz, |
---|
121 | lsu_ifu_t1_tlz, lsu_ifu_t2_tlz, lsu_ifu_t3_tlz, tlu_ifu_hwint_i3, |
---|
122 | tlu_ifu_pstate_ie, tlu_ifu_sftint_vld, tlu_ifu_hintp_vld, |
---|
123 | tlu_ifu_rerr_vld, tlu_ifu_rstthr_i2, tlu_ifu_rstint_i2, |
---|
124 | tlu_ifu_resumint_i2, tlu_ifu_nukeint_i2, tlu_itlb_wr_vld_g, |
---|
125 | tlu_itlb_dmp_vld_g, tlu_itlb_dmp_all_g, tlu_itlb_data_rd_g, |
---|
126 | tlu_itlb_tag_rd_g, tlu_itlb_invalidate_all_g, tlu_fcl_dmp_pid_bf, |
---|
127 | tlu_fcl_dmp_real_bf, tlu_idtlb_dmp_thrid_g, exu_ifu_ecc_ce_m, |
---|
128 | ffu_ifu_fst_ce_w |
---|
129 | ); |
---|
130 | |
---|
131 | input rclk, |
---|
132 | grst_l, |
---|
133 | arst_l, |
---|
134 | se, |
---|
135 | sehold, |
---|
136 | si; |
---|
137 | |
---|
138 | input rst_tri_en; |
---|
139 | |
---|
140 | |
---|
141 | input tlu_ifu_flush_pipe_w; // flush pipe on a trap |
---|
142 | input exu_ifu_va_oor_m; |
---|
143 | input [3:0] exu_ifu_oddwin_s; |
---|
144 | |
---|
145 | input [1:0] spu_ifu_ttype_tid_w2; |
---|
146 | input spu_ifu_ttype_vld_w2; |
---|
147 | input spu_ifu_ttype_w2; |
---|
148 | |
---|
149 | input [3:0] erb_fcl_spu_uetrap; // use m3 |
---|
150 | |
---|
151 | // input dtu_fcl_brtaken_e; // branch taken |
---|
152 | input exu_ifu_regz_e; |
---|
153 | input dcl_fcl_bcregz0_e, |
---|
154 | dcl_fcl_bcregz1_e; |
---|
155 | |
---|
156 | input dtu_fcl_rollback_g; |
---|
157 | input dtu_fcl_retract_d; |
---|
158 | input dtu_fcl_br_inst_d; |
---|
159 | input dtu_fcl_sir_inst_e; |
---|
160 | input dtu_fcl_privop_e, |
---|
161 | dtu_fcl_fpdis_e, |
---|
162 | dtu_fcl_imask_hit_e, |
---|
163 | dtu_fcl_illinst_e; |
---|
164 | input [3:0] dtu_fcl_thr_active; |
---|
165 | |
---|
166 | input dec_fcl_rdsr_sel_pc_d, |
---|
167 | dec_fcl_rdsr_sel_thr_d; |
---|
168 | |
---|
169 | input ifq_fcl_wrreq_bf; |
---|
170 | input ifq_fcl_icd_wrreq_bf, |
---|
171 | ifq_fcl_ictv_wrreq_bf, |
---|
172 | ifq_fcl_rdreq_bf; |
---|
173 | |
---|
174 | input [1:0] ifq_fcl_asi_tid_bf; |
---|
175 | input ifq_fcl_asird_bf; |
---|
176 | |
---|
177 | input ifq_fcl_invreq_bf; |
---|
178 | |
---|
179 | input erb_fcl_itlb_ce_d1; |
---|
180 | input erb_dtu_ifeterr_d1; |
---|
181 | input [3:0] erb_fcl_ifet_uevec_d1, |
---|
182 | erb_fcl_ue_trapvec, |
---|
183 | erb_fcl_ce_trapvec; |
---|
184 | |
---|
185 | input [3:0] dtu_fcl_nextthr_bf; // thread to switch to |
---|
186 | input dtu_fcl_ntr_s, // next thread ready for ex |
---|
187 | dtu_fcl_running_s; |
---|
188 | |
---|
189 | input dtu_fcl_flush_sonly_e; |
---|
190 | // dec_fcl_kill4sta_e; |
---|
191 | |
---|
192 | input fdp_fcl_swc_s2, // instruction switch condition |
---|
193 | fdp_fcl_va2_bf, // bit 2 of vaddr |
---|
194 | itlb_fcl_tlbmiss_f_l, // itlb miss |
---|
195 | itlb_fcl_priv_s1, // privileged access page |
---|
196 | itlb_fcl_cp_s1, // uncached access page |
---|
197 | itlb_fcl_imiss_s_l; // icache miss in s1 |
---|
198 | |
---|
199 | input [3:0] fdp_fcl_pc_oor_vec_f; |
---|
200 | input fdp_fcl_pc_oor_e; |
---|
201 | |
---|
202 | input [1:0] fdp_fcl_op_s; |
---|
203 | input [5:2] fdp_fcl_op3_s; |
---|
204 | input fdp_fcl_ibit_s; |
---|
205 | |
---|
206 | input lsu_ifu_stallreq, |
---|
207 | ffu_ifu_stallreq, |
---|
208 | ifq_fcl_stallreq; |
---|
209 | |
---|
210 | input dtu_inst_anull_e; |
---|
211 | |
---|
212 | input [3:0] ifq_fcl_fill_thr; // fill inst goes to this |
---|
213 | // thread instruction register |
---|
214 | input ifq_fcl_flush_sonly_e; |
---|
215 | |
---|
216 | input [1:0] tlu_ifu_trap_tid_w1; // thr for which trappc is sent |
---|
217 | input tlu_ifu_trappc_vld_w1, // ld pc on trap or done/retry |
---|
218 | tlu_ifu_trapnpc_vld_w1; // ld Npc for a retry |
---|
219 | |
---|
220 | input [3:0] tlu_lsu_pstate_priv; // may need to flop these three |
---|
221 | input [3:0] tlu_lsu_pstate_am; |
---|
222 | input [3:0] tlu_hpstate_priv; |
---|
223 | input [3:0] tlu_lsu_redmode; |
---|
224 | input [3:0] tlu_hpstate_enb; |
---|
225 | |
---|
226 | input [3:0] lsu_ifu_addr_real_l; |
---|
227 | input [2:0] lsu_pid_state0, |
---|
228 | lsu_pid_state1, |
---|
229 | lsu_pid_state2, |
---|
230 | lsu_pid_state3; |
---|
231 | input [3:0] lsu_ifu_icache_en; |
---|
232 | |
---|
233 | input lsu_ifu_dc_parity_error_w2; |
---|
234 | |
---|
235 | |
---|
236 | // input lsu_ifu_flush_ireg; // not needed any more |
---|
237 | input lsu_ifu_t0_tlz, |
---|
238 | lsu_ifu_t1_tlz, |
---|
239 | lsu_ifu_t2_tlz, |
---|
240 | lsu_ifu_t3_tlz; |
---|
241 | |
---|
242 | input [3:0] tlu_ifu_hwint_i3, // normal interrupt |
---|
243 | tlu_ifu_pstate_ie, |
---|
244 | tlu_ifu_sftint_vld, |
---|
245 | tlu_ifu_hintp_vld, |
---|
246 | tlu_ifu_rerr_vld, |
---|
247 | tlu_ifu_rstthr_i2; // reset or idle interrupt |
---|
248 | |
---|
249 | input tlu_ifu_rstint_i2, // reset to a dead thread |
---|
250 | tlu_ifu_resumint_i2, |
---|
251 | tlu_ifu_nukeint_i2; |
---|
252 | |
---|
253 | input tlu_itlb_wr_vld_g, |
---|
254 | tlu_itlb_dmp_vld_g, |
---|
255 | tlu_itlb_dmp_all_g, |
---|
256 | tlu_itlb_data_rd_g, |
---|
257 | tlu_itlb_tag_rd_g; |
---|
258 | input tlu_itlb_invalidate_all_g; |
---|
259 | |
---|
260 | input [2:0] tlu_fcl_dmp_pid_bf; |
---|
261 | input tlu_fcl_dmp_real_bf; |
---|
262 | input [1:0] tlu_idtlb_dmp_thrid_g; |
---|
263 | |
---|
264 | input exu_ifu_ecc_ce_m; |
---|
265 | input ffu_ifu_fst_ce_w; |
---|
266 | |
---|
267 | // to icd |
---|
268 | output fcl_icd_rdreq_bf, |
---|
269 | fcl_icv_rdreq_bf, |
---|
270 | fcl_icd_wrreq_bf, |
---|
271 | fcl_ict_wrreq_bf, |
---|
272 | fcl_icv_wrreq_bf; |
---|
273 | |
---|
274 | output fcl_icd_index_sel_ifq_bf; |
---|
275 | output fcl_ifq_grant_bf; |
---|
276 | |
---|
277 | // to ifq |
---|
278 | output fcl_ifq_icmiss_s1; // if icache turned off |
---|
279 | output fcl_ifq_rdreq_s1; |
---|
280 | output fcl_ifq_icache_en_s_l; |
---|
281 | |
---|
282 | output [1:0] fcl_ifq_thr_s1; |
---|
283 | output [3:0] fcl_ifq_canthr; // cancel ifetch to this thread |
---|
284 | |
---|
285 | // to itlb |
---|
286 | output fcl_itlb_cam_vld_bf, |
---|
287 | fcl_itlb_cam_bypass_bf, |
---|
288 | fcl_itlb_addr_mask_l, |
---|
289 | fcl_itlb_cam_real_bf; |
---|
290 | |
---|
291 | output [2:0] fcl_itlb_cam_pid_bf; |
---|
292 | |
---|
293 | output fcl_itlb_wr_vld_bf, |
---|
294 | fcl_itlb_dmp_vld_bf, |
---|
295 | fcl_itlb_dmp_all_bf, |
---|
296 | fcl_itlb_tag_rd_vld_bf, |
---|
297 | fcl_itlb_invall_f_l, |
---|
298 | fcl_itlb_data_rd_vld_bf; |
---|
299 | |
---|
300 | // to erb |
---|
301 | output fcl_erb_ievld_s1, |
---|
302 | fcl_erb_tevld_s1, |
---|
303 | fcl_erb_immuevld_s1; |
---|
304 | |
---|
305 | output [1:0] ifu_lsu_thrid_s, |
---|
306 | fcl_erb_asi_tid_f; |
---|
307 | |
---|
308 | output [3:0] fcl_erb_clear_iferr; |
---|
309 | |
---|
310 | |
---|
311 | output fcl_erb_itlbrd_vld_s, |
---|
312 | fcl_erb_itlbrd_data_s; |
---|
313 | |
---|
314 | output fcl_dec_dslot_s; |
---|
315 | output fcl_dtu_inst_vld_e, |
---|
316 | fcl_dtu_intr_vld_e, |
---|
317 | fcl_dtu_inst_vld_d, |
---|
318 | fcl_dtu_ely_inst_vld_d, |
---|
319 | fcl_dec_intr_vld_d, |
---|
320 | fcl_erb_inst_issue_d, |
---|
321 | fcl_erb_inst_vld_d1, |
---|
322 | ifu_tlu_inst_vld_m, |
---|
323 | // ifu_lsu_inst_vld_m, |
---|
324 | ifu_exu_inst_vld_e, |
---|
325 | ifu_exu_inst_vld_w, |
---|
326 | ifu_spu_inst_vld_w, |
---|
327 | ifu_tlu_inst_vld_w; |
---|
328 | |
---|
329 | output ifu_tlu_flush_w; |
---|
330 | output ifu_tlu_flush_m; |
---|
331 | |
---|
332 | output [3:0] fcl_swl_int_activate_i3; |
---|
333 | output fcl_swl_flush_wake_w; |
---|
334 | output fcl_swl_flush_w; |
---|
335 | |
---|
336 | output fcl_dcl_regz_e; |
---|
337 | |
---|
338 | // to tlu |
---|
339 | output [1:0] ifu_tlu_thrid_e; |
---|
340 | output [1:0] ifu_tlu_thrid_d; |
---|
341 | |
---|
342 | output ifu_tlu_immu_miss_m, |
---|
343 | ifu_tlu_priv_violtn_m; |
---|
344 | |
---|
345 | output ifu_tlu_icmiss_e; |
---|
346 | output ifu_tlu_ttype_vld_m; |
---|
347 | output ifu_exu_ttype_vld_m; |
---|
348 | output ifu_mmu_trap_m; |
---|
349 | output ifu_tlu_trap_m; |
---|
350 | output [8:0] ifu_tlu_ttype_m; |
---|
351 | |
---|
352 | output ifu_tlu_hwint_m; |
---|
353 | output ifu_tlu_sftint_m; |
---|
354 | // output ifu_tlu_hintp_m; |
---|
355 | // output ifu_tlu_rerr_m; |
---|
356 | output ifu_tlu_rstint_m; |
---|
357 | output fcl_dtu_rst_thr_w; |
---|
358 | output fcl_dtu_resum_thr_w; |
---|
359 | |
---|
360 | output ifu_tlu_itlb_done; |
---|
361 | |
---|
362 | output ifu_spu_trap_ack; |
---|
363 | |
---|
364 | // to exu |
---|
365 | output [1:0] ifu_exu_tid_s2; |
---|
366 | output ifu_exu_ren1_s, |
---|
367 | ifu_exu_ren2_s, |
---|
368 | ifu_exu_ren3_s; |
---|
369 | |
---|
370 | output ifu_exu_disable_ce_e; // to exu and ffu |
---|
371 | |
---|
372 | |
---|
373 | // to dtu |
---|
374 | output fcl_dtu_sync_intr_d; |
---|
375 | output fcl_dtu_tlzero_d; |
---|
376 | output fcl_dtu_privmode_d; |
---|
377 | output fcl_dtu_hprivmode_d; |
---|
378 | output fcl_dtu_hprivmode_w2; |
---|
379 | output fcl_dtu_nuke_thr_w; |
---|
380 | output fcl_swl_swout_f; |
---|
381 | output fcl_dtu_stall_bf; |
---|
382 | // output fcl_dtu_switch_s; // indicates to the DTU that a |
---|
383 | // switch took place to next_thr |
---|
384 | output fcl_swl_swcvld_s; |
---|
385 | output [3:0] fcl_dtu_thr_f; |
---|
386 | output fcl_imd_oddwin_d; |
---|
387 | |
---|
388 | // to fdp |
---|
389 | output fcl_fdp_oddwin_s; |
---|
390 | output [3:0] fcl_fdp_pcoor_vec_f; |
---|
391 | output fcl_fdp_pcoor_f; |
---|
392 | output fcl_fdp_mask32b_f; |
---|
393 | output fcl_fdp_addr_mask_d; |
---|
394 | |
---|
395 | output [3:0] fcl_fdp_tctxt_sel_prim; |
---|
396 | |
---|
397 | |
---|
398 | // 2:1 mux selects |
---|
399 | output fcl_fdp_usenir_sel_nir_s1; // same as usenir_d2 |
---|
400 | output [3:0] fcl_fdp_rbinst_sel_inste_s; |
---|
401 | |
---|
402 | output [3:0] fcl_fdp_thrtnpc_sel_tnpc_l, // load npc |
---|
403 | fcl_fdp_thrtnpc_sel_npcw_l, |
---|
404 | fcl_fdp_thrtnpc_sel_pcf_l, |
---|
405 | fcl_fdp_thrtnpc_sel_old_l; |
---|
406 | |
---|
407 | output [3:0] fcl_fdp_thr_s1_l; // s1 thr for thrNIR input mux |
---|
408 | |
---|
409 | // other mux selects |
---|
410 | output [3:0] fcl_fdp_next_thr_bf_l, // for thrpc output mux |
---|
411 | fcl_fdp_next_ctxt_bf_l, // for ctxt output mux |
---|
412 | fcl_fdp_nirthr_s1_l, // select NIR in s1 stage |
---|
413 | fcl_fdp_thr_s2_l; // s2 thr for thr_inst_reg |
---|
414 | |
---|
415 | output [3:0] fcl_fdp_tpcbf_sel_pcp4_bf_l, // selects for thread PC muxes |
---|
416 | fcl_fdp_tpcbf_sel_brpc_bf_l, |
---|
417 | fcl_fdp_tpcbf_sel_trap_bf_l, |
---|
418 | fcl_fdp_tpcbf_sel_old_bf_l; |
---|
419 | |
---|
420 | output fcl_fdp_pcbf_sel_nosw_bf_l, // F stage pc mux selects |
---|
421 | fcl_fdp_pcbf_sel_swpc_bf_l, |
---|
422 | fcl_fdp_pcbf_sel_br_bf_l; |
---|
423 | |
---|
424 | output [3:0] fcl_fdp_trrbpc_sel_trap_bf_l, |
---|
425 | fcl_fdp_trrbpc_sel_rb_bf_l, |
---|
426 | fcl_fdp_trrbpc_sel_err_bf_l, |
---|
427 | fcl_fdp_trrbpc_sel_pcs_bf_l; |
---|
428 | |
---|
429 | output fcl_fdp_noswpc_sel_tnpc_l_bf, // next pc select, |
---|
430 | fcl_fdp_noswpc_sel_old_l_bf, // dont need anymore |
---|
431 | fcl_fdp_noswpc_sel_inc_l_bf; |
---|
432 | |
---|
433 | output [3:0] fcl_fdp_nextpcs_sel_pce_f_l, |
---|
434 | fcl_fdp_nextpcs_sel_pcd_f_l, |
---|
435 | fcl_fdp_nextpcs_sel_pcs_f_l, |
---|
436 | fcl_fdp_nextpcs_sel_pcf_f_l; |
---|
437 | |
---|
438 | output fcl_fdp_inst_sel_curr_s_l, // selects for inst_s2 |
---|
439 | fcl_fdp_inst_sel_switch_s_l, |
---|
440 | fcl_fdp_inst_sel_nir_s_l, |
---|
441 | fcl_fdp_inst_sel_nop_s_l; |
---|
442 | |
---|
443 | output [3:0] fcl_fdp_tinst_sel_curr_s_l, // selects for tinst regs |
---|
444 | fcl_fdp_tinst_sel_rb_s_l, |
---|
445 | fcl_fdp_tinst_sel_old_s_l, |
---|
446 | fcl_fdp_tinst_sel_ifq_s_l; |
---|
447 | |
---|
448 | output [3:0] fcl_fdp_dmpthr_l; |
---|
449 | |
---|
450 | output fcl_fdp_ctxt_sel_dmp_bf_l, |
---|
451 | fcl_fdp_ctxt_sel_sw_bf_l, |
---|
452 | fcl_fdp_ctxt_sel_curr_bf_l; |
---|
453 | |
---|
454 | output fcl_fdp_rdsr_sel_pc_e_l, |
---|
455 | fcl_fdp_rdsr_sel_thr_e_l, |
---|
456 | fcl_fdp_rdsr_sel_ver_e_l; |
---|
457 | |
---|
458 | output so, |
---|
459 | ifu_reset_l; |
---|
460 | |
---|
461 | |
---|
462 | //---------------------------------------------------------------------- |
---|
463 | // Declarations |
---|
464 | //---------------------------------------------------------------------- |
---|
465 | reg [3:0] fcl_fdp_tpcbf_sel_old_bf_l, |
---|
466 | fcl_fdp_tpcbf_sel_pcp4_bf_l, |
---|
467 | fcl_fdp_tpcbf_sel_trap_bf_l, |
---|
468 | fcl_fdp_tpcbf_sel_brpc_bf_l; |
---|
469 | |
---|
470 | wire fcl_fdp_inst_sel_nop_s_l, |
---|
471 | fcl_fdp_inst_sel_nir_s_l, |
---|
472 | fcl_fdp_inst_sel_curr_s_l, |
---|
473 | fcl_fdp_inst_sel_switch_s_l; |
---|
474 | |
---|
475 | |
---|
476 | // local signals |
---|
477 | wire //sw_itlb_on, |
---|
478 | sw_itlb_real, |
---|
479 | sw_itlb_am, |
---|
480 | //this_itlb_on, |
---|
481 | this_itlb_real, |
---|
482 | itlb_on; |
---|
483 | |
---|
484 | wire [3:0] xlate_en, |
---|
485 | xlate_en_d1; |
---|
486 | |
---|
487 | wire [2:0] sw_pid_bf, |
---|
488 | curr_pid_bf; |
---|
489 | |
---|
490 | wire pid_sel_sw, |
---|
491 | pid_sel_curr, |
---|
492 | pid_sel_dmp; |
---|
493 | |
---|
494 | wire itlb_access_gnt, |
---|
495 | itlb_access_en, |
---|
496 | itlb_write_en, |
---|
497 | ctxt_sel_dmp, |
---|
498 | itlb_access_done, |
---|
499 | itlb_write_done, |
---|
500 | itlb_rd_access_done, |
---|
501 | itlb_rd_access_done_d1, |
---|
502 | itlb_rd_access_done_d2, |
---|
503 | itlb_rd_req_bf, |
---|
504 | itlb_rd_req_f, |
---|
505 | itlb_data_rd_f, |
---|
506 | itlb_data_rd_s; |
---|
507 | |
---|
508 | wire [1:0] asi_tid_bf; |
---|
509 | wire [1:0] spu_tid_w2; |
---|
510 | |
---|
511 | wire fetch_bf, // fetch an instruction next cycle |
---|
512 | allow_ifq_access_icd_bf, |
---|
513 | inst_access_bf, |
---|
514 | ia1_bf, |
---|
515 | ia0_bf, |
---|
516 | no_instacc_bf; |
---|
517 | |
---|
518 | wire cam_vld_bf, |
---|
519 | tlb_invall_bf, |
---|
520 | tlb_invall_f, |
---|
521 | // tlb_invall_req_bf, |
---|
522 | inst_vld_bf; |
---|
523 | |
---|
524 | wire rdreq_bf, // read from I$ next cycle |
---|
525 | rdreq_f; |
---|
526 | |
---|
527 | wire ic_wrreq_bf; |
---|
528 | |
---|
529 | wire running_s2, |
---|
530 | valid_s, |
---|
531 | running_s1, |
---|
532 | ely_running_s1, |
---|
533 | running_d, |
---|
534 | running_e, |
---|
535 | running_m, |
---|
536 | inst_vld_f, |
---|
537 | inst_vld_s, |
---|
538 | inst_vld_s_crit, |
---|
539 | inst_vld_s1, |
---|
540 | inst_vld_s2, // valid bit of S stage |
---|
541 | // instruction. If this is 0, |
---|
542 | // convert inst to no-op |
---|
543 | inst_vld_d, |
---|
544 | inst_vld_d_crit, |
---|
545 | inst_vld_d1, |
---|
546 | inst_vld_e, |
---|
547 | inst_vld_qual_e, |
---|
548 | inst_vld_m, |
---|
549 | inst_vld_w; |
---|
550 | |
---|
551 | wire inst_vld_w_crit; |
---|
552 | |
---|
553 | wire no_iftrap_m, |
---|
554 | no_iftrap_w; |
---|
555 | |
---|
556 | wire stall_f, |
---|
557 | stall_s1, |
---|
558 | stall_s1_nxt, |
---|
559 | ely_stall_thisthr_f, |
---|
560 | part_stall_thisthr_f, |
---|
561 | stall_thisthr_f; |
---|
562 | wire rdreq_s1; |
---|
563 | |
---|
564 | wire usenir_bf, |
---|
565 | usenir_f, |
---|
566 | usenir_s1; |
---|
567 | |
---|
568 | wire [3:0] tinst_vld_s, // valid bit of thr instr register |
---|
569 | // in s stage |
---|
570 | tinst_vld_nxt; |
---|
571 | |
---|
572 | wire [3:0] val_thr_s1, |
---|
573 | val_thr_f, |
---|
574 | thr_e_v2, |
---|
575 | val_thr_e; |
---|
576 | |
---|
577 | wire flush_sonly_qual_e, |
---|
578 | flush_sonly_all_m, |
---|
579 | flush_sonly_qual_m, |
---|
580 | ims_flush_sonly_m, |
---|
581 | ims_flush_sonly_w, |
---|
582 | ims_flush_coll_m, |
---|
583 | ims_flush_coll_w, |
---|
584 | flush_sonly_m; |
---|
585 | |
---|
586 | wire flush_pipe_w; |
---|
587 | |
---|
588 | wire kill_thread_d, |
---|
589 | // kill_thread_e, |
---|
590 | kill_thread_m, |
---|
591 | kill_local_m, |
---|
592 | ely_kill_thread_s2, |
---|
593 | ely_kill_thread_m, |
---|
594 | kill_thread_s2; |
---|
595 | |
---|
596 | wire [3:0] clear_s_d1, |
---|
597 | flush_thr_w, |
---|
598 | late_flush_w2; |
---|
599 | |
---|
600 | wire utrap_flush_w, |
---|
601 | utrap_flush_m, |
---|
602 | flush_pipe_w2; |
---|
603 | |
---|
604 | wire kill_curr_f, |
---|
605 | kill_curr_d, |
---|
606 | kill_curr_e, |
---|
607 | kill_curr_m; |
---|
608 | |
---|
609 | wire [3:0] canthr_f, |
---|
610 | canthr_s_early, |
---|
611 | canthr_s; |
---|
612 | wire canthr_sw; |
---|
613 | wire canthr_sm, |
---|
614 | canthr_sd; |
---|
615 | |
---|
616 | wire forcemiss_f, // force an icache miss (if icache is off) |
---|
617 | forcemiss_s1, |
---|
618 | icmiss_for_perf, |
---|
619 | // ic_miss_sw_s1, |
---|
620 | ic_miss_s1; // icache miss (forced or not) |
---|
621 | |
---|
622 | wire [3:0] icache_en_d1; |
---|
623 | |
---|
624 | wire icache_on_bf, |
---|
625 | icache_on_f, |
---|
626 | icache_on_s1, |
---|
627 | uncached_page_s1; |
---|
628 | // sw_icache_on, |
---|
629 | // this_icache_on; |
---|
630 | |
---|
631 | wire imsto_thisthr_s1, |
---|
632 | iferrto_thisthr_d1, |
---|
633 | retract_iferr_d1, |
---|
634 | retract_iferr_qual_d1, |
---|
635 | retract_inst_d, |
---|
636 | retract_iferr_e; |
---|
637 | // wire intrto_thisthr_d; |
---|
638 | // wire imsto_nextthr_s1; |
---|
639 | |
---|
640 | wire mark4rb_w, |
---|
641 | mark4rb_m, |
---|
642 | mark4rb_e, |
---|
643 | mark4rb_d, |
---|
644 | mark4rb_s; |
---|
645 | |
---|
646 | wire [3:0] tlbmiss_s2, |
---|
647 | tlbmiss_d, |
---|
648 | nir_tlbmiss_vec, |
---|
649 | nir_tlbmiss_next; |
---|
650 | |
---|
651 | wire [3:0] delay_slot_vec, |
---|
652 | delay_slot_vec_nxt; |
---|
653 | |
---|
654 | wire tlb_cam_miss_f, |
---|
655 | tlb_cam_miss_s1, |
---|
656 | nir_tlbmiss_s1, |
---|
657 | tlbmiss_s1_crit, |
---|
658 | tlbmiss_s1; |
---|
659 | |
---|
660 | wire cam_vld_f, |
---|
661 | cam_vld_s1; |
---|
662 | |
---|
663 | wire immu_fault_f, |
---|
664 | immu_miss_d, |
---|
665 | immu_miss_crit_d, |
---|
666 | immu_miss_qual_d, |
---|
667 | immu_miss_e, |
---|
668 | // immu_miss_qual_e, |
---|
669 | immu_miss_m, |
---|
670 | addr_real_e; |
---|
671 | wire [3:0] itlb_addr_real_l, |
---|
672 | itlb_addr_real; |
---|
673 | wire [3:0] pstate_am_d1; |
---|
674 | |
---|
675 | wire pc_oor_s1, |
---|
676 | pc_oor_s2, |
---|
677 | pc_oor_s, |
---|
678 | pc_oor_f; |
---|
679 | wire set_oor_m; |
---|
680 | wire addr_mask_32b_m; |
---|
681 | |
---|
682 | wire priv_mode_s1, |
---|
683 | priv_mode_f, |
---|
684 | hpriv_mode_s1, |
---|
685 | hpriv_mode_w, |
---|
686 | hpriv_mode_w2, |
---|
687 | hpriv_mode_f; |
---|
688 | |
---|
689 | wire inst_acc_exc_s1, |
---|
690 | inst_acc_exc_d, |
---|
691 | inst_acc_exc_e; |
---|
692 | wire [3:0] inst_acc_vec_s2, |
---|
693 | inst_acc_vec_d; |
---|
694 | |
---|
695 | wire priv_violtn_e, |
---|
696 | priv_violtn_m; |
---|
697 | |
---|
698 | wire trap_e, |
---|
699 | trap_m; |
---|
700 | |
---|
701 | wire ttype_sel_spuma_e, |
---|
702 | ttype_sel_spuenc_e, |
---|
703 | ttype_sel_corr_err_e, |
---|
704 | ttype_sel_unc_err_e, |
---|
705 | ttype_sel_res_err_e, |
---|
706 | ttype_sel_hstk_cmp_e, |
---|
707 | ttype_sel_pcoor_e, |
---|
708 | ttype_sel_immu_miss_e, |
---|
709 | ttype_sel_real_trans_e, |
---|
710 | ttype_sel_icache_err_e, |
---|
711 | ttype_sel_priv_viol_e, |
---|
712 | ttype_sel_privop_e, |
---|
713 | ttype_sel_illinst_e, |
---|
714 | ttype_sel_ibe_e, |
---|
715 | ttype_sel_sir_e, |
---|
716 | ttype_sel_fpdis_e; |
---|
717 | |
---|
718 | wire [8:0] ttype_e; |
---|
719 | |
---|
720 | wire [3:0] next_nir_privvec, |
---|
721 | nir_privvec; |
---|
722 | wire nir_priv_s1, |
---|
723 | priv_inst_s1; |
---|
724 | |
---|
725 | wire tlzero_s2; |
---|
726 | wire [3:0] tlzero_vec_d1; |
---|
727 | |
---|
728 | wire nuke_thr_w, |
---|
729 | resum_thr_w, |
---|
730 | rst_thr_w; |
---|
731 | |
---|
732 | wire [3:0] spu_thr; |
---|
733 | // wire [3:0] rst_thr_bf; |
---|
734 | |
---|
735 | wire [3:0] async_rst_i3, |
---|
736 | async_rst_i4, |
---|
737 | next_rst_i2, |
---|
738 | rstint_i2, |
---|
739 | rstint_i3, |
---|
740 | resumint_i2, |
---|
741 | resumint_i3, |
---|
742 | next_resum_i2, |
---|
743 | nuke_thr_i2, |
---|
744 | next_nuke_i2, |
---|
745 | nuke_thr_i3, |
---|
746 | next_sftint_i2, |
---|
747 | next_hintp_i2, |
---|
748 | next_rerr_i2, |
---|
749 | next_hwint_i3, |
---|
750 | sftint_i3, |
---|
751 | hintp_i3, |
---|
752 | rerr_i3, |
---|
753 | hwint_i4, |
---|
754 | next_ceint_i2, |
---|
755 | ceint_i3, |
---|
756 | next_ueint_i2, |
---|
757 | ueint_i3, |
---|
758 | next_spuint0_i2, |
---|
759 | spuint0_i3, |
---|
760 | next_spuint1_i2, |
---|
761 | spuint1_i3; |
---|
762 | |
---|
763 | wire [3:0] intr_in_pipe; |
---|
764 | |
---|
765 | wire [3:0] hypv_int_en, |
---|
766 | hypv_int_en_d1; |
---|
767 | wire [3:0] supv_int_en, |
---|
768 | supv_int_en_d1; |
---|
769 | |
---|
770 | wire [3:0] ifet_ue_vec_d1, |
---|
771 | ifet_ue_vec_e; |
---|
772 | wire ifet_ue_e; |
---|
773 | |
---|
774 | wire [3:0] any_intr_vec_f, |
---|
775 | any_intr_vec_s, |
---|
776 | intr_pending_nxt, |
---|
777 | intr_pending_s, |
---|
778 | supv_masked_intr_s, |
---|
779 | hypv_masked_intr_s; |
---|
780 | |
---|
781 | wire spuint0_m, |
---|
782 | spuint0_trap_m, |
---|
783 | // spuint0_qual_m, |
---|
784 | spuint0_e, |
---|
785 | spuint0_qual_e, |
---|
786 | spuint0_w, |
---|
787 | spuint0_trap_w, |
---|
788 | spuint1_m, |
---|
789 | spuint1_trap_m, |
---|
790 | // spuint1_qual_m, |
---|
791 | spuint1_e, |
---|
792 | spuint1_qual_e, |
---|
793 | spuint1_w, |
---|
794 | spuint1_trap_w, |
---|
795 | hwint_m, |
---|
796 | hwint_e, |
---|
797 | rstint_m, |
---|
798 | // rstint_qual_m, |
---|
799 | resumint_m, |
---|
800 | resumint_qual_m, |
---|
801 | sftint_m, |
---|
802 | sftint_e, |
---|
803 | sftint_qual_e, |
---|
804 | hintp_e, |
---|
805 | hintp_qual_e, |
---|
806 | hintp_m, |
---|
807 | rerr_e, |
---|
808 | rerr_qual_e, |
---|
809 | rerr_m, |
---|
810 | nuke_thr_m, |
---|
811 | nuke_thr_qual_m, |
---|
812 | ceint_m, |
---|
813 | ceint_trap_m, |
---|
814 | ceint_trap_w, |
---|
815 | // ceint_qual_m, |
---|
816 | ceint_qual_w, |
---|
817 | ceint_e, |
---|
818 | ceint_qual_e, |
---|
819 | ueint_m, |
---|
820 | ueint_trap_m, |
---|
821 | ueint_trap_w, |
---|
822 | // ueint_qual_m, |
---|
823 | ueint_qual_w, |
---|
824 | ueint_qual_e, |
---|
825 | ueint_e; |
---|
826 | |
---|
827 | wire disr_trap_m, |
---|
828 | rb_intr_m, |
---|
829 | rb_intr_w, |
---|
830 | any_intr_m; |
---|
831 | |
---|
832 | wire force_intr_s; |
---|
833 | wire intr_vld_s, |
---|
834 | intr_vld_d, |
---|
835 | intr_vld_e, |
---|
836 | intr_vld_m, |
---|
837 | intr_vld_w, |
---|
838 | intr_vld_qual_s, |
---|
839 | intr_vld_qual_d, |
---|
840 | intr_vld_qual_e, |
---|
841 | intr_vld_qual_m; |
---|
842 | |
---|
843 | wire kill_intr_f, |
---|
844 | kill_intr_d, |
---|
845 | kill_intr_e; |
---|
846 | |
---|
847 | // wire kill_intr_m; |
---|
848 | |
---|
849 | wire rst_stallreq, |
---|
850 | rst_stallreq_l, |
---|
851 | all_stallreq, |
---|
852 | rst_itlb_stv_l, |
---|
853 | arst_vld_f, |
---|
854 | arst_vld_f_l, |
---|
855 | arst_vld_s, |
---|
856 | arst_vld_s_l, |
---|
857 | async_intr_vld_s, |
---|
858 | itlb_starv_alert, |
---|
859 | rst_sw_bf, |
---|
860 | rst_sw_bf_l, |
---|
861 | sw_for_real_rst_bf, |
---|
862 | rst_stallreq_d0, |
---|
863 | rst_stallreq_d1, |
---|
864 | rst_stallreq_d2; |
---|
865 | |
---|
866 | wire lsu_stallreq_d1, |
---|
867 | ffu_stallreq_d1; |
---|
868 | |
---|
869 | wire [3:0] rstint_penc; |
---|
870 | |
---|
871 | wire usep_bf, |
---|
872 | set_usen_bf, |
---|
873 | usen_iso_bf, |
---|
874 | usen_bf; |
---|
875 | wire va2_f; |
---|
876 | wire ntpc_thisthr; |
---|
877 | |
---|
878 | wire [3:0] thr_usen_nxt, |
---|
879 | thr_usen_bf; |
---|
880 | |
---|
881 | wire brto_nxtthr_bf_l, // intermediate signal for icadr sel |
---|
882 | // brto_nxtthr_bf, |
---|
883 | // thr_match_ne_norst, |
---|
884 | sw_match_ne_norst, |
---|
885 | brtaken_buf_e, |
---|
886 | brtaken_unq_e, |
---|
887 | brtaken_e, |
---|
888 | brtaken_m; |
---|
889 | |
---|
890 | wire switch_bf, // switch in next cycle unless stall |
---|
891 | switch_qual_bf, |
---|
892 | switch_s2; // switch in this cycle |
---|
893 | |
---|
894 | wire rstt, // set thr_f to the reset pkt thread |
---|
895 | swt, // switch to nextthr_bf |
---|
896 | samet; // don't change thread |
---|
897 | |
---|
898 | wire [3:0] thr_f_crit, |
---|
899 | thr_f_dec, |
---|
900 | thr_f_flop; |
---|
901 | |
---|
902 | wire [3:0] thr_f, // = thr_s2 |
---|
903 | thr_bf, |
---|
904 | thr_s1, // = thr_d |
---|
905 | thr_s1_next, |
---|
906 | dec_thr_s1_l, |
---|
907 | thr_d, |
---|
908 | thr_e, |
---|
909 | thr_m, |
---|
910 | thr_w2, |
---|
911 | thr_w; |
---|
912 | |
---|
913 | wire tm_fd_l; |
---|
914 | |
---|
915 | wire thr_match_fw, |
---|
916 | thr_match_fw2, |
---|
917 | thr_match_dw, |
---|
918 | thr_match_dw2, |
---|
919 | thr_match_em, |
---|
920 | thr_match_ew, |
---|
921 | thr_match_ew2, |
---|
922 | same_thr_mw2, |
---|
923 | thr_match_mw, |
---|
924 | thr_match_fm, |
---|
925 | thr_match_de, |
---|
926 | thr_match_dm, |
---|
927 | thr_match_fe, |
---|
928 | thr_match_fd, |
---|
929 | thr_match_fs1, |
---|
930 | thr_match_nw, |
---|
931 | thr_match_nd, |
---|
932 | thr_match_ne; |
---|
933 | // thr_match_ft; |
---|
934 | |
---|
935 | wire rb2_inst_d, |
---|
936 | rb2_inst_e, |
---|
937 | rb1_inst_s, |
---|
938 | rb1_inst_d, |
---|
939 | rb0_inst_bf, |
---|
940 | rb0_inst_s, |
---|
941 | rt2_inst_e, |
---|
942 | rt1_inst_s, |
---|
943 | rt1_inst_d, |
---|
944 | rt0_inst_bf, |
---|
945 | rt0_inst_s; |
---|
946 | |
---|
947 | wire [3:0] rb_w2, |
---|
948 | rb_for_iferr_e, |
---|
949 | rb_froms, |
---|
950 | rb_frome, |
---|
951 | rb_fromd; |
---|
952 | |
---|
953 | wire rb_stg_s, |
---|
954 | rb_stg_d, |
---|
955 | rb_stg_d_crit, |
---|
956 | rb_stg_e; |
---|
957 | |
---|
958 | wire icadr_selbr_l, |
---|
959 | // icadr_selsw, |
---|
960 | // icadr_selbr, |
---|
961 | icadr_selsw_l; |
---|
962 | |
---|
963 | wire sw_or_async_stall; |
---|
964 | |
---|
965 | wire [3:0] trap_thr; |
---|
966 | |
---|
967 | wire [3:0] load_tpc, // thread pc reg input select |
---|
968 | load_bpc, // these should be exclusive in normal mode |
---|
969 | load_pcp4; // but not during scan shift or reset |
---|
970 | |
---|
971 | wire irf_ce_w, |
---|
972 | irf_ce_m, |
---|
973 | any_ce_w, |
---|
974 | rb_stg_w; |
---|
975 | |
---|
976 | wire [3:0] ce_cnt0, |
---|
977 | ce_cnt0_nxt, |
---|
978 | ce_cnt1, |
---|
979 | ce_cnt1_nxt, |
---|
980 | ce_cnt_rst; |
---|
981 | |
---|
982 | wire ce_val0_d, |
---|
983 | ce_val1_d, |
---|
984 | disable_ce_e, |
---|
985 | disable_ce_d; |
---|
986 | |
---|
987 | wire [3:0] ntpc_vld, // use thr_nextpc_f |
---|
988 | ntpc_vld_nxt; |
---|
989 | |
---|
990 | wire [1:0] sas_thrid_w; |
---|
991 | |
---|
992 | wire rdsr_sel_pc_e, |
---|
993 | rdsr_sel_thr_e; |
---|
994 | |
---|
995 | wire [1:0] trap_tid_w2; |
---|
996 | wire trappc_vld_w2, |
---|
997 | trapnpc_vld_w2; |
---|
998 | |
---|
999 | wire fcl_reset, |
---|
1000 | fcl_reset_l; |
---|
1001 | |
---|
1002 | // some monitor is looking for this signal |
---|
1003 | // wire fcl_swl_flush_wait_w=1'b0; |
---|
1004 | wire clk; |
---|
1005 | |
---|
1006 | wire [3:0] nextthr_bf_buf, |
---|
1007 | nextthr_final_bf; |
---|
1008 | |
---|
1009 | |
---|
1010 | // |
---|
1011 | // Code start here |
---|
1012 | // |
---|
1013 | assign clk = rclk; |
---|
1014 | |
---|
1015 | //---------------------------------------------------------------------- |
---|
1016 | // Fetch Unit Controls |
---|
1017 | //---------------------------------------------------------------------- |
---|
1018 | |
---|
1019 | // reset buffer |
---|
1020 | dffrl_async rstff(.din (grst_l), |
---|
1021 | .q (fcl_reset_l), |
---|
1022 | .clk (clk), .se(se), .si(), .so(), |
---|
1023 | .rst_l (arst_l)); |
---|
1024 | |
---|
1025 | assign fcl_reset = ~fcl_reset_l; |
---|
1026 | assign ifu_reset_l = fcl_reset_l; |
---|
1027 | |
---|
1028 | |
---|
1029 | //----------------------------------- |
---|
1030 | // TLB Operations |
---|
1031 | //----------------------------------- |
---|
1032 | |
---|
1033 | dff_s #(4) real_reg(.din (lsu_ifu_addr_real_l), |
---|
1034 | .q (itlb_addr_real_l), |
---|
1035 | .clk (clk), .se(se), .si(), .so()); |
---|
1036 | assign itlb_addr_real = ~itlb_addr_real_l; |
---|
1037 | |
---|
1038 | // ITLB on signal |
---|
1039 | |
---|
1040 | //`ifdef SPARC_HPV_EN |
---|
1041 | assign xlate_en = (~tlu_hpstate_enb & lsu_ifu_addr_real_l | |
---|
1042 | tlu_hpstate_enb & ~tlu_hpstate_priv) & |
---|
1043 | ~tlu_lsu_redmode; |
---|
1044 | |
---|
1045 | //`else |
---|
1046 | // assign xlate_en = lsu_ifu_addr_real_l; |
---|
1047 | //`endif |
---|
1048 | |
---|
1049 | dff_s #(4) xlate_reg(.din (xlate_en), |
---|
1050 | .q (xlate_en_d1), |
---|
1051 | .clk (clk), .se(se), .si(), .so()); |
---|
1052 | |
---|
1053 | // assign sw_itlb_on = ((nextthr_bf_buf & xlate_en_d1) == 4'b0) ? |
---|
1054 | // 1'b0 : 1'b1; |
---|
1055 | // assign this_itlb_on = ((thr_f & xlate_en_d1) == 4'b0) ? |
---|
1056 | // 1'b0 : 1'b1; |
---|
1057 | // assign itlb_on = switch_bf ? sw_itlb_on : this_itlb_on; |
---|
1058 | assign itlb_on = (nextthr_final_bf[0] & xlate_en_d1[0] | |
---|
1059 | nextthr_final_bf[1] & xlate_en_d1[1] | |
---|
1060 | nextthr_final_bf[2] & xlate_en_d1[2] | |
---|
1061 | nextthr_final_bf[3] & xlate_en_d1[3]); |
---|
1062 | |
---|
1063 | |
---|
1064 | // flop xlate_en (done) addr_real and icache_en if timing is |
---|
1065 | // not cutting it |
---|
1066 | |
---|
1067 | // Hypervisor signals |
---|
1068 | assign sw_itlb_real = ((nextthr_bf_buf & itlb_addr_real) == 4'b0) ? |
---|
1069 | 1'b0 : 1'b1; |
---|
1070 | assign this_itlb_real = ((thr_f & itlb_addr_real) == 4'b0) ? |
---|
1071 | 1'b0 : 1'b1; |
---|
1072 | |
---|
1073 | // assign fcl_itlb_cam_real_bf = switch_bf ? sw_itlb_real : this_itlb_real; |
---|
1074 | |
---|
1075 | mux3ds creal_mx(.dout (fcl_itlb_cam_real_bf), |
---|
1076 | .in0 (sw_itlb_real), |
---|
1077 | .in1 (this_itlb_real), |
---|
1078 | .in2 (tlu_fcl_dmp_real_bf), |
---|
1079 | .sel0 (pid_sel_sw), |
---|
1080 | .sel1 (pid_sel_curr), |
---|
1081 | .sel2 (pid_sel_dmp)); |
---|
1082 | |
---|
1083 | // Partition ID |
---|
1084 | mux4ds #(3) swpid_mux (.dout (sw_pid_bf[2:0]), |
---|
1085 | .in0 (lsu_pid_state0[2:0]), |
---|
1086 | .in1 (lsu_pid_state1[2:0]), |
---|
1087 | .in2 (lsu_pid_state2[2:0]), |
---|
1088 | .in3 (lsu_pid_state3[2:0]), |
---|
1089 | .sel0 (nextthr_bf_buf[0]), |
---|
1090 | .sel1 (nextthr_bf_buf[1]), |
---|
1091 | .sel2 (nextthr_bf_buf[2]), |
---|
1092 | .sel3 (nextthr_bf_buf[3])); |
---|
1093 | |
---|
1094 | mux4ds #(3) currpid_mux (.dout (curr_pid_bf[2:0]), |
---|
1095 | .in0 (lsu_pid_state0[2:0]), |
---|
1096 | .in1 (lsu_pid_state1[2:0]), |
---|
1097 | .in2 (lsu_pid_state2[2:0]), |
---|
1098 | .in3 (lsu_pid_state3[2:0]), |
---|
1099 | .sel0 (thr_f[0]), |
---|
1100 | .sel1 (thr_f[1]), |
---|
1101 | .sel2 (thr_f[2]), |
---|
1102 | .sel3 (thr_f[3])); |
---|
1103 | |
---|
1104 | // assign fcl_itlb_cam_pid_bf[2:0] = switch_bf ? |
---|
1105 | // sw_pid_bf[2:0] : |
---|
1106 | // curr_pid_bf[2:0]; |
---|
1107 | |
---|
1108 | // assign pid_sel_dmp = tlu_itlb_dmp_actxt_g & ctxt_sel_dmp; |
---|
1109 | assign pid_sel_dmp = ctxt_sel_dmp; |
---|
1110 | assign pid_sel_curr = ~pid_sel_dmp & ~switch_bf; |
---|
1111 | assign pid_sel_sw = ~pid_sel_dmp & switch_bf; |
---|
1112 | mux3ds #(3) ipid_mx(.dout (fcl_itlb_cam_pid_bf[2:0]), |
---|
1113 | .in0 (sw_pid_bf[2:0]), |
---|
1114 | .in1 (curr_pid_bf[2:0]), |
---|
1115 | .in2 (tlu_fcl_dmp_pid_bf[2:0]), |
---|
1116 | .sel0 (pid_sel_sw), |
---|
1117 | .sel1 (pid_sel_curr), |
---|
1118 | .sel2 (pid_sel_dmp)); |
---|
1119 | |
---|
1120 | // ITLB address mask |
---|
1121 | dff_s #(4) am_reg(.din (tlu_lsu_pstate_am), |
---|
1122 | .q (pstate_am_d1), |
---|
1123 | .clk (clk), .se(se), .si(), .so()); |
---|
1124 | |
---|
1125 | assign sw_itlb_am = ((nextthr_bf_buf & pstate_am_d1) == 4'b0) ? |
---|
1126 | 1'b0 : 1'b1; |
---|
1127 | assign fcl_itlb_addr_mask_l = switch_bf ? |
---|
1128 | ~sw_itlb_am : ~fcl_fdp_mask32b_f; |
---|
1129 | |
---|
1130 | dff_s #(4) tlz_reg(.din ({lsu_ifu_t3_tlz, |
---|
1131 | lsu_ifu_t2_tlz, |
---|
1132 | lsu_ifu_t1_tlz, |
---|
1133 | lsu_ifu_t0_tlz}), |
---|
1134 | .q (tlzero_vec_d1[3:0]), |
---|
1135 | .clk (clk), .se (se), .si(), .so()); |
---|
1136 | |
---|
1137 | |
---|
1138 | // TLB context select |
---|
1139 | assign fcl_fdp_tctxt_sel_prim = tlzero_vec_d1 & itlb_addr_real_l; |
---|
1140 | // assign fcl_fdp_tctxt_sel_prim[1] = lsu_ifu_t1_tlz & itlb_addr_real_l[1]; |
---|
1141 | // assign fcl_fdp_tctxt_sel_prim[2] = lsu_ifu_t2_tlz & itlb_addr_real_l[2]; |
---|
1142 | // assign fcl_fdp_tctxt_sel_prim[3] = lsu_ifu_t3_tlz & itlb_addr_real_l[3]; |
---|
1143 | |
---|
1144 | |
---|
1145 | // Access to TLB |
---|
1146 | // ITLB may be accessed even when icache is off |
---|
1147 | assign cam_vld_bf = itlb_on & inst_access_bf; |
---|
1148 | |
---|
1149 | assign fcl_itlb_cam_vld_bf = cam_vld_bf; |
---|
1150 | assign fcl_itlb_cam_bypass_bf = ~cam_vld_bf; |
---|
1151 | |
---|
1152 | dff_s #(1) itlb_onf_ff(.din (cam_vld_bf), |
---|
1153 | .q (cam_vld_f), |
---|
1154 | .clk (clk), |
---|
1155 | .se (se), .si(), .so()); |
---|
1156 | |
---|
1157 | dff_s #(1) itlb_ons1_ff(.din (cam_vld_f), |
---|
1158 | .q (cam_vld_s1), |
---|
1159 | .clk (clk), |
---|
1160 | .se (se), .si(), .so()); |
---|
1161 | |
---|
1162 | // allow rd/wr/demap access to tlb |
---|
1163 | // itlb access is granted only every other cycle |
---|
1164 | // (not enough time to turn the request from mmu around) |
---|
1165 | // assign itlb_access_en = ~cam_vld_bf & ~ifq_fcl_asird_bf & |
---|
1166 | // ~itlb_access_done; |
---|
1167 | // |
---|
1168 | // assign itlb_write_en = ~cam_vld_bf & ~ifq_fcl_asird_bf & |
---|
1169 | // ~itlb_write_done & |
---|
1170 | // (~tlu_itlb_dmp_vld_g | itlb_access_done); |
---|
1171 | |
---|
1172 | // Save some timing |
---|
1173 | // assign itlb_write_en = (~itlb_on | no_instacc_bf) & ~ifq_fcl_asird_bf & |
---|
1174 | // ~itlb_write_done & |
---|
1175 | // (~tlu_itlb_dmp_vld_g | itlb_access_done); |
---|
1176 | |
---|
1177 | assign itlb_write_en = no_instacc_bf & ~ifq_fcl_asird_bf & |
---|
1178 | ~itlb_write_done & |
---|
1179 | (~tlu_itlb_dmp_vld_g | itlb_access_done); |
---|
1180 | assign itlb_access_en = no_instacc_bf & ~ifq_fcl_asird_bf & |
---|
1181 | ~itlb_access_done; |
---|
1182 | |
---|
1183 | // reset tlb |
---|
1184 | // dff #(1) itlbrst_ff(.din (tlu_itlb_invalidate_all_g), |
---|
1185 | // .q (tlb_invall_req_bf), |
---|
1186 | // .clk (clk), .se(se), .si(), .so()); |
---|
1187 | // assign tlb_invall_bf = tlb_invall_req_bf & ~itlb_access_done; |
---|
1188 | assign tlb_invall_bf = sehold ? tlb_invall_f : |
---|
1189 | (tlu_itlb_invalidate_all_g & itlb_access_en); |
---|
1190 | dff_s #(1) itlbrstf_ff(.din (tlb_invall_bf), |
---|
1191 | .q (tlb_invall_f), |
---|
1192 | .clk (clk), .se(se), .si(), .so()); |
---|
1193 | |
---|
1194 | assign fcl_itlb_wr_vld_bf = tlu_itlb_wr_vld_g & itlb_write_en; |
---|
1195 | assign fcl_itlb_dmp_vld_bf = tlu_itlb_dmp_vld_g & itlb_access_en; |
---|
1196 | assign fcl_itlb_dmp_all_bf = tlu_itlb_dmp_all_g & tlu_itlb_dmp_vld_g & |
---|
1197 | itlb_access_en; |
---|
1198 | |
---|
1199 | // assign fcl_itlb_invall_bf = tlb_invall_bf & itlb_access_en | fcl_reset; |
---|
1200 | assign fcl_itlb_invall_f_l = ~tlb_invall_f; |
---|
1201 | |
---|
1202 | assign fcl_itlb_data_rd_vld_bf = tlu_itlb_data_rd_g & itlb_access_en & |
---|
1203 | ~itlb_rd_access_done_d2 & |
---|
1204 | ~itlb_rd_access_done_d1; |
---|
1205 | |
---|
1206 | assign fcl_itlb_tag_rd_vld_bf = tlu_itlb_tag_rd_g & itlb_access_en & |
---|
1207 | ~itlb_rd_access_done_d2 & |
---|
1208 | ~itlb_rd_access_done_d1; |
---|
1209 | |
---|
1210 | assign rst_itlb_stv_l = ((tlu_itlb_invalidate_all_g | |
---|
1211 | tlu_itlb_dmp_vld_g | |
---|
1212 | tlu_itlb_data_rd_g | |
---|
1213 | tlu_itlb_tag_rd_g) & ~itlb_access_done | |
---|
1214 | tlu_itlb_wr_vld_g & ~itlb_write_done) & |
---|
1215 | ~fcl_reset; |
---|
1216 | |
---|
1217 | sparc_ifu_ctr5 starv_ctr( |
---|
1218 | // Outputs |
---|
1219 | .limit (itlb_starv_alert), |
---|
1220 | .so (so), |
---|
1221 | // Inputs |
---|
1222 | .clk (clk), |
---|
1223 | .se (se), |
---|
1224 | .si (si), |
---|
1225 | .rst_ctr_l (rst_itlb_stv_l)); |
---|
1226 | |
---|
1227 | assign itlb_rd_req_bf = fcl_itlb_data_rd_vld_bf | fcl_itlb_tag_rd_vld_bf; |
---|
1228 | |
---|
1229 | // tlb access request |
---|
1230 | assign itlb_access_gnt = (fcl_itlb_data_rd_vld_bf | |
---|
1231 | fcl_itlb_tag_rd_vld_bf | |
---|
1232 | // tlb_invall_bf & itlb_access_en | |
---|
1233 | tlb_invall_bf | |
---|
1234 | fcl_itlb_dmp_vld_bf); |
---|
1235 | |
---|
1236 | dff_s #(1) tlb_gnt1_ff(.din (itlb_access_gnt), |
---|
1237 | .q (itlb_access_done), |
---|
1238 | .clk (clk), .se (se), .si(), .so()); |
---|
1239 | |
---|
1240 | dff_s #(1) tlb_rd_ff(.din (itlb_rd_req_bf), |
---|
1241 | .q (itlb_rd_req_f), |
---|
1242 | .clk (clk), .se (se), .si(), .so()); |
---|
1243 | |
---|
1244 | dff_s #(1) tlb_wrt1_ff(.din (fcl_itlb_wr_vld_bf), |
---|
1245 | .q (itlb_write_done), |
---|
1246 | .clk (clk), .se (se), .si(), .so()); |
---|
1247 | |
---|
1248 | |
---|
1249 | // TBD: |
---|
1250 | // reads need to wait one more cycle. Others can ack without this |
---|
1251 | // second delay. |
---|
1252 | assign itlb_rd_access_done = itlb_rd_req_f & itlb_access_done; |
---|
1253 | |
---|
1254 | dff_s #(1) tlb_rd1_ff(.din (itlb_rd_access_done), |
---|
1255 | .q (itlb_rd_access_done_d1), |
---|
1256 | .clk (clk), .se (se), .si(), .so()); |
---|
1257 | dff_s #(1) tlb_rd2_ff(.din (itlb_rd_access_done_d1), |
---|
1258 | .q (itlb_rd_access_done_d2), |
---|
1259 | .clk (clk), .se (se), .si(), .so()); |
---|
1260 | assign ifu_tlu_itlb_done = ~itlb_rd_req_f & itlb_access_done | |
---|
1261 | itlb_write_done | |
---|
1262 | itlb_rd_access_done_d2; |
---|
1263 | |
---|
1264 | assign fcl_erb_itlbrd_vld_s = itlb_rd_access_done_d1; |
---|
1265 | |
---|
1266 | assign asi_tid_bf = ifq_fcl_asird_bf ? ifq_fcl_asi_tid_bf : |
---|
1267 | tlu_idtlb_dmp_thrid_g; |
---|
1268 | |
---|
1269 | dff_s #(2) asi_tid_reg(.din (asi_tid_bf), |
---|
1270 | .q (fcl_erb_asi_tid_f), |
---|
1271 | .clk (clk), .se(se), .si(), .so()); |
---|
1272 | |
---|
1273 | |
---|
1274 | // Remember if we read tag or data |
---|
1275 | dff_s #(1) tlb_rddf_ff(.din (fcl_itlb_data_rd_vld_bf), |
---|
1276 | .q (itlb_data_rd_f), |
---|
1277 | .clk (clk), .se (se), .si(), .so()); |
---|
1278 | |
---|
1279 | dff_s #(1) tlb_rdds_ff(.din (itlb_data_rd_f), |
---|
1280 | .q (itlb_data_rd_s), |
---|
1281 | .clk (clk), .se (se), .si(), .so()); |
---|
1282 | |
---|
1283 | // pick itlb ldxa data |
---|
1284 | assign fcl_erb_itlbrd_data_s = itlb_data_rd_s; |
---|
1285 | |
---|
1286 | // Demap thread |
---|
1287 | assign fcl_fdp_dmpthr_l[0] = ~(~tlu_idtlb_dmp_thrid_g[1] & ~tlu_idtlb_dmp_thrid_g[0]); |
---|
1288 | assign fcl_fdp_dmpthr_l[1] = ~(~tlu_idtlb_dmp_thrid_g[1] & tlu_idtlb_dmp_thrid_g[0]); |
---|
1289 | assign fcl_fdp_dmpthr_l[2] = ~(tlu_idtlb_dmp_thrid_g[1] & ~tlu_idtlb_dmp_thrid_g[0]); |
---|
1290 | assign fcl_fdp_dmpthr_l[3] = ~(tlu_idtlb_dmp_thrid_g[1] & tlu_idtlb_dmp_thrid_g[0]); |
---|
1291 | |
---|
1292 | // Select appropriate context for TLB |
---|
1293 | // ctxt_sel_dmp is itlb_access_en without the asird signal |
---|
1294 | assign ctxt_sel_dmp = no_instacc_bf & ~itlb_access_done; |
---|
1295 | assign fcl_fdp_ctxt_sel_dmp_bf_l = ~ctxt_sel_dmp; |
---|
1296 | assign fcl_fdp_ctxt_sel_sw_bf_l = ctxt_sel_dmp | ~switch_bf; |
---|
1297 | assign fcl_fdp_ctxt_sel_curr_bf_l = ctxt_sel_dmp | switch_bf; |
---|
1298 | |
---|
1299 | |
---|
1300 | //-------------------------- |
---|
1301 | // Fetch Request and Stall |
---|
1302 | //-------------------------- |
---|
1303 | |
---|
1304 | // Determine if we need can continue fetching next cycle |
---|
1305 | // assign fetch_bf = (~all_stallreq & ~fcl_reset & ~rst_stallreq) & |
---|
1306 | // (switch_bf | |
---|
1307 | // ~(part_stall_thisthr_f | fdp_fcl_swc_s2)); |
---|
1308 | // ~(stall_thisthr_f | fdp_fcl_swc_s2 | immu_fault_f)); |
---|
1309 | |
---|
1310 | assign fetch_bf = (~all_stallreq & ~fcl_reset & ~rst_stallreq) & |
---|
1311 | (switch_bf | // replace with ntr_s? |
---|
1312 | ~(part_stall_thisthr_f |
---|
1313 | | fdp_fcl_swc_s2 |
---|
1314 | ) |
---|
1315 | ); |
---|
1316 | |
---|
1317 | // dtu_fcl_running_s should be a part of this eqn, since it is assumed |
---|
1318 | // by the ifill completion prediction logic in the swl |
---|
1319 | // assign inst_access_bf = (~all_stallreq & ~fcl_reset & ~rst_stallreq & |
---|
1320 | // (switch_bf & ~usen_iso_bf | |
---|
1321 | // ~switch_bf & ~ely_stall_thisthr_f & |
---|
1322 | // dtu_fcl_running_s & |
---|
1323 | // ~ely_kill_thread_s2 & |
---|
1324 | // //~fdp_fcl_swc_s2 & // take out for tim reasons |
---|
1325 | // ~usep_bf)); |
---|
1326 | |
---|
1327 | assign ia0_bf = (~all_stallreq & ~fcl_reset & ~rst_stallreq & |
---|
1328 | (switch_bf | |
---|
1329 | ~ely_stall_thisthr_f & |
---|
1330 | dtu_fcl_running_s & |
---|
1331 | ~ely_kill_thread_s2 & |
---|
1332 | ~usep_bf)); |
---|
1333 | |
---|
1334 | assign ia1_bf = (~all_stallreq & ~fcl_reset & ~rst_stallreq & |
---|
1335 | (~switch_bf & ~ely_stall_thisthr_f & |
---|
1336 | dtu_fcl_running_s & |
---|
1337 | ~ely_kill_thread_s2 & |
---|
1338 | ~usep_bf)); |
---|
1339 | |
---|
1340 | |
---|
1341 | assign inst_access_bf = usen_iso_bf ? ia1_bf : ia0_bf; |
---|
1342 | // needs to work even if usen_iso_bf is X - not nec. 11/06/03 |
---|
1343 | // dp_mux2es #(1) ia_mx(.dout (inst_access_bf), |
---|
1344 | // .in0 (ia0_bf), |
---|
1345 | // .in1 (ia1_bf), |
---|
1346 | // .sel (usen_iso_bf)); |
---|
1347 | |
---|
1348 | |
---|
1349 | |
---|
1350 | // assign allow_ifq_access_icd_bf = (all_stallreq | rs |
---|
1351 | // ~switch_bf & |
---|
1352 | // (usep_bf | stall_f) | |
---|
1353 | // switch_bf & usen_bf); |
---|
1354 | assign allow_ifq_access_icd_bf = ~inst_access_bf; |
---|
1355 | |
---|
1356 | // earlier version for critical stuff |
---|
1357 | assign no_instacc_bf = all_stallreq | fcl_reset | rst_stallreq | |
---|
1358 | ~dtu_fcl_ntr_s & (ely_stall_thisthr_f | usep_bf); |
---|
1359 | |
---|
1360 | // check if icache is on |
---|
1361 | dff_s #(4) ic_en_reg(.din (lsu_ifu_icache_en), |
---|
1362 | .q (icache_en_d1), |
---|
1363 | .clk (clk), .se(se), .si(), .so()); |
---|
1364 | |
---|
1365 | // assign sw_icache_on = (nextthr_bf_buf[0] & icache_en_d1[0] | |
---|
1366 | // nextthr_bf_buf[1] & icache_en_d1[1] | |
---|
1367 | // nextthr_bf_buf[2] & icache_en_d1[2] | |
---|
1368 | // nextthr_bf_buf[3] & icache_en_d1[3]); |
---|
1369 | // assign this_icache_on = (thr_f[0] & icache_en_d1[0] | |
---|
1370 | // thr_f[1] & icache_en_d1[1] | |
---|
1371 | // thr_f[2] & icache_en_d1[2] | |
---|
1372 | // thr_f[3] & icache_en_d1[3]); |
---|
1373 | // assign icache_on_bf = switch_bf ? sw_icache_on : this_icache_on; |
---|
1374 | |
---|
1375 | assign icache_on_bf = (nextthr_final_bf[0] & icache_en_d1[0] | |
---|
1376 | nextthr_final_bf[1] & icache_en_d1[1] | |
---|
1377 | nextthr_final_bf[2] & icache_en_d1[2] | |
---|
1378 | nextthr_final_bf[3] & icache_en_d1[3]); |
---|
1379 | |
---|
1380 | // remember if icache was turned on |
---|
1381 | dff_s #(1) icef_ff(.din (icache_on_bf), |
---|
1382 | .q (icache_on_f), |
---|
1383 | .clk (clk), .se(se), .si(), .so()); |
---|
1384 | dff_s #(1) ices_ff(.din (icache_on_f), |
---|
1385 | .q (icache_on_s1), |
---|
1386 | .clk (clk), .se(se), .si(), .so()); |
---|
1387 | |
---|
1388 | // check if cp is set |
---|
1389 | assign uncached_page_s1 = ~itlb_fcl_cp_s1 & cam_vld_s1; |
---|
1390 | assign fcl_ifq_icache_en_s_l = ~icache_on_s1 | uncached_page_s1; |
---|
1391 | |
---|
1392 | // Read from the icache only if |
---|
1393 | // we need to fetch AND |
---|
1394 | // the icache is on AND |
---|
1395 | // we are not using the NIR |
---|
1396 | assign rdreq_bf = icache_on_bf & inst_access_bf; |
---|
1397 | |
---|
1398 | assign fcl_icd_rdreq_bf = rdreq_bf | ifq_fcl_rdreq_bf; |
---|
1399 | |
---|
1400 | // split off driver to icv to reduce load |
---|
1401 | assign fcl_icv_rdreq_bf = rdreq_bf | ifq_fcl_rdreq_bf; |
---|
1402 | |
---|
1403 | // Read req pipe |
---|
1404 | dffr_s #(1) rdreq_ff(.din (rdreq_bf), |
---|
1405 | .clk (clk), |
---|
1406 | .rst (fcl_reset), |
---|
1407 | .q (rdreq_f), |
---|
1408 | .se (se), .si(), .so()); |
---|
1409 | // Remember if we fetched in the last cycle |
---|
1410 | dff_s #(1) rdreqs1_ff (.din (rdreq_f), |
---|
1411 | .clk (clk), |
---|
1412 | .q (rdreq_s1), |
---|
1413 | .se (se), .si(), .so()); |
---|
1414 | assign fcl_ifq_rdreq_s1 = ~stall_s1; |
---|
1415 | |
---|
1416 | // Use NIR pipe |
---|
1417 | assign usenir_bf = switch_bf ? usen_bf : usep_bf; |
---|
1418 | |
---|
1419 | dffr_s #(1) unf_ff(.din (usenir_bf), |
---|
1420 | .clk (clk), |
---|
1421 | .rst (fcl_reset), |
---|
1422 | .q (usenir_f), |
---|
1423 | .se (se), .si(), .so()); |
---|
1424 | // Remember if we fetched in the last cycle |
---|
1425 | dff_s #(1) uns1_ff (.din (usenir_f), |
---|
1426 | .clk (clk), |
---|
1427 | .q (usenir_s1), |
---|
1428 | .se (se), .si(), .so()); |
---|
1429 | |
---|
1430 | |
---|
1431 | // Write signal to icache if no access from pipe |
---|
1432 | assign ic_wrreq_bf = allow_ifq_access_icd_bf & ifq_fcl_wrreq_bf; |
---|
1433 | |
---|
1434 | assign fcl_icd_wrreq_bf = ic_wrreq_bf | ifq_fcl_icd_wrreq_bf; |
---|
1435 | assign fcl_ict_wrreq_bf = ic_wrreq_bf | ifq_fcl_ictv_wrreq_bf; |
---|
1436 | assign fcl_icv_wrreq_bf = ic_wrreq_bf | ifq_fcl_ictv_wrreq_bf | |
---|
1437 | ifq_fcl_invreq_bf; |
---|
1438 | |
---|
1439 | // synopsys translate_off |
---|
1440 | always @ (posedge clk) |
---|
1441 | begin |
---|
1442 | if (fcl_icd_rdreq_bf & fcl_icd_wrreq_bf) |
---|
1443 | begin |
---|
1444 | // 0in <fire -message "ERROR: sparc_ifu_fcl: rd and wr req to I$ at the same time" |
---|
1445 | `ifdef DEFINE_0IN |
---|
1446 | `else |
---|
1447 | `ifdef MODELSIM |
---|
1448 | $display( "CACHE_CONTENTION", "ERROR: sparc_ifu_fcl: rd and wr req to I$ at the same time"); |
---|
1449 | `else |
---|
1450 | $error("CACHE_CONTENTION", "ERROR: sparc_ifu_fcl: rd and wr req to I$ at the same time"); |
---|
1451 | `endif |
---|
1452 | `endif |
---|
1453 | end |
---|
1454 | end |
---|
1455 | // synopsys translate_on |
---|
1456 | |
---|
1457 | |
---|
1458 | //------------------------- |
---|
1459 | // Valid Instruction Pipe |
---|
1460 | //------------------------- |
---|
1461 | // F stage |
---|
1462 | assign inst_vld_bf = fetch_bf; |
---|
1463 | dff_s #(1) inst_vld_ff(.din (inst_vld_bf), |
---|
1464 | .clk (clk), |
---|
1465 | .q (inst_vld_f), |
---|
1466 | .se (se), .si(), .so()); |
---|
1467 | |
---|
1468 | assign stall_f = ~inst_vld_f | kill_curr_f; |
---|
1469 | assign stall_thisthr_f = stall_f | imsto_thisthr_s1 | // intrto_thisthr_d | |
---|
1470 | kill_thread_s2 | rb_stg_s | ~dtu_fcl_running_s | |
---|
1471 | iferrto_thisthr_d1; |
---|
1472 | |
---|
1473 | assign part_stall_thisthr_f = stall_f | |
---|
1474 | imsto_thisthr_s1 | |
---|
1475 | ~dtu_fcl_running_s | |
---|
1476 | ely_kill_thread_s2 | |
---|
1477 | rb_stg_s; |
---|
1478 | |
---|
1479 | assign ely_stall_thisthr_f = stall_f | rb_stg_s; |
---|
1480 | |
---|
1481 | // assign stall_s1_nxt = stall_thisthr_f | intr_vld_s | tmsto_thisthr_f; |
---|
1482 | assign stall_s1_nxt = stall_thisthr_f; //| intr_vld_s; |
---|
1483 | |
---|
1484 | // S1 stage |
---|
1485 | dff_s #(1) stalld_ff(.din (stall_s1_nxt), |
---|
1486 | .clk (clk), |
---|
1487 | .q (stall_s1), |
---|
1488 | .se (se), .si(), .so()); |
---|
1489 | |
---|
1490 | assign inst_vld_s1 = ~stall_s1 & ~ic_miss_s1 & ~kill_curr_d; |
---|
1491 | assign val_thr_s1 = thr_s1 & {4{inst_vld_s1}}; // 4b |
---|
1492 | |
---|
1493 | // S2 stage |
---|
1494 | assign val_thr_f = thr_f & {4{~stall_f & ~rb_stg_s & dtu_fcl_running_s}}; |
---|
1495 | |
---|
1496 | // Tag the S stage thr inst register as containing a valid inst or not |
---|
1497 | assign tinst_vld_nxt = (ifq_fcl_fill_thr | |
---|
1498 | (rb_w2 & ~rb_for_iferr_e) | // set |
---|
1499 | val_thr_s1 & ~val_thr_f | |
---|
1500 | // val_thr_s1 | |
---|
1501 | tinst_vld_s & ~val_thr_f) & |
---|
1502 | ~(clear_s_d1 | |
---|
1503 | {4{erb_dtu_ifeterr_d1 & inst_vld_d1 & |
---|
1504 | ~rb_stg_e}} & thr_e); // reset |
---|
1505 | |
---|
1506 | dffr_s #(4) tinst_reg(.din (tinst_vld_nxt), |
---|
1507 | .clk (clk), |
---|
1508 | .rst (fcl_reset), |
---|
1509 | .q (tinst_vld_s), |
---|
1510 | .se (se), .si(), .so()); |
---|
1511 | |
---|
1512 | // Does current thread have valid inst in s2 |
---|
1513 | assign inst_vld_s2 = ((thr_f_crit & tinst_vld_s) == 4'b0000) ? |
---|
1514 | {1'b0} : {1'b1}; |
---|
1515 | |
---|
1516 | assign inst_vld_s = ~switch_s2 & inst_vld_s1 | |
---|
1517 | switch_s2 & inst_vld_s2; |
---|
1518 | assign inst_vld_s_crit = ~switch_s2 & ~stall_s1 & ~kill_curr_d | |
---|
1519 | switch_s2 & inst_vld_s2; |
---|
1520 | |
---|
1521 | assign valid_s = inst_vld_s & ~stall_f & // f and s2 have same thread |
---|
1522 | dtu_fcl_running_s & |
---|
1523 | ~(ely_kill_thread_s2 | rb_stg_s); |
---|
1524 | |
---|
1525 | assign running_s2 = inst_vld_s & ~stall_thisthr_f;// f and s2 have |
---|
1526 | // same thread |
---|
1527 | // D stage |
---|
1528 | dff_s #(1) rund_ff(.din (running_s2), |
---|
1529 | .clk (clk), |
---|
1530 | .q (inst_vld_d), |
---|
1531 | .se (se), .si(), .so()); |
---|
1532 | dff_s #(1) eivd_ff(.din (running_s2), |
---|
1533 | .clk (clk), |
---|
1534 | .q (inst_vld_d_crit), |
---|
1535 | .se (se), .si(), .so()); |
---|
1536 | assign fcl_erb_inst_issue_d = inst_vld_d & ~intr_vld_d; |
---|
1537 | assign running_d = inst_vld_d & ~kill_thread_d & ~rb_stg_d & |
---|
1538 | ~intr_vld_d; |
---|
1539 | |
---|
1540 | // E stage |
---|
1541 | dff_s #(1) rune_ff(.din (running_d), |
---|
1542 | .clk (clk), |
---|
1543 | .q (inst_vld_e), |
---|
1544 | .se (se), .si(), .so()); |
---|
1545 | |
---|
1546 | assign running_e = inst_vld_e & ~dtu_inst_anull_e & |
---|
1547 | ~kill_curr_e & ~rb_stg_e & |
---|
1548 | ~(thr_match_em & ifu_tlu_flush_m); |
---|
1549 | assign inst_vld_qual_e = inst_vld_e & ~rb_stg_e; |
---|
1550 | assign val_thr_e = thr_e_v2 & {4{inst_vld_qual_e}} & ~late_flush_w2 & |
---|
1551 | ~(thr_w & {4{utrap_flush_w}}); |
---|
1552 | |
---|
1553 | |
---|
1554 | // M stage |
---|
1555 | dff_s #(1) runm_ff(.din (running_e), |
---|
1556 | .clk (clk), |
---|
1557 | .q (inst_vld_m), |
---|
1558 | .se (se), .si(), .so()); |
---|
1559 | assign running_m = (inst_vld_m | intr_vld_m) & ~kill_thread_m; |
---|
1560 | |
---|
1561 | assign ifu_tlu_inst_vld_m = (inst_vld_m | intr_vld_m) & ~kill_curr_m; |
---|
1562 | // less critical |
---|
1563 | // assign ifu_lsu_inst_vld_m = ifu_tlu_inst_vld_m; |
---|
1564 | |
---|
1565 | // W stage |
---|
1566 | dff_s #(1) runw_ff(.din (running_m), |
---|
1567 | .q (inst_vld_w), |
---|
1568 | .clk (clk), .se (se), .si(), .so()); |
---|
1569 | |
---|
1570 | dff_s #(1) iw_ff(.din (running_m), |
---|
1571 | .q (inst_vld_w_crit), |
---|
1572 | .clk (clk), .se (se), .si(), .so()); |
---|
1573 | |
---|
1574 | // synopsys translate_off |
---|
1575 | // wire sas_m, |
---|
1576 | // inst_done_w_for_sas; |
---|
1577 | |
---|
1578 | // assign sas_m = inst_vld_m & ~kill_thread_m & |
---|
1579 | // ~(exu_ifu_ecc_ce_m & inst_vld_m & ~trap_m); |
---|
1580 | |
---|
1581 | // dff #(1) sasw_ff(.din (sas_m), |
---|
1582 | // .clk (clk), |
---|
1583 | // .q (inst_done_w_for_sas), |
---|
1584 | // .se (se), .si(), .so()); |
---|
1585 | // synopsys translate_on |
---|
1586 | |
---|
1587 | // need to kill branch by E stage, so qual with rb_stg_X |
---|
1588 | assign fcl_dtu_inst_vld_e = inst_vld_e & ~rb_stg_e & ~kill_curr_e; |
---|
1589 | assign fcl_dtu_intr_vld_e = intr_vld_e & ~rb_stg_e & ~kill_curr_e; |
---|
1590 | assign fcl_dtu_inst_vld_d = inst_vld_d & ~kill_curr_d & |
---|
1591 | ~rb_stg_d_crit & ~immu_miss_crit_d; |
---|
1592 | assign fcl_dtu_ely_inst_vld_d = inst_vld_d_crit; |
---|
1593 | assign ifu_tlu_inst_vld_w = inst_vld_w; |
---|
1594 | assign ifu_exu_inst_vld_w = inst_vld_w_crit; |
---|
1595 | assign ifu_spu_inst_vld_w = inst_vld_w; |
---|
1596 | assign ifu_exu_inst_vld_e = fcl_dtu_inst_vld_e; |
---|
1597 | |
---|
1598 | assign flush_sonly_qual_e = dtu_fcl_flush_sonly_e & inst_vld_e & |
---|
1599 | // ~dec_fcl_kill4sta_e & |
---|
1600 | ~rb_stg_e & ~dtu_inst_anull_e & ~kill_curr_e; |
---|
1601 | |
---|
1602 | |
---|
1603 | dff_s #(1) flshm_ff(.din (flush_sonly_qual_e), |
---|
1604 | .q (flush_sonly_m), |
---|
1605 | .clk (clk), |
---|
1606 | .se (se), .si(), .so()); |
---|
1607 | |
---|
1608 | dff_s #(1) imflshm_ff(.din (ifq_fcl_flush_sonly_e), |
---|
1609 | .q (ims_flush_sonly_m), |
---|
1610 | .clk (clk), |
---|
1611 | .se (se), .si(), .so()); |
---|
1612 | // detect collision between two different types of retractions |
---|
1613 | assign ims_flush_coll_m = ims_flush_sonly_m & ~canthr_sm & |
---|
1614 | retract_iferr_e; |
---|
1615 | dff_s #(1) imflshw_ff(.din (ims_flush_coll_m), |
---|
1616 | .q (ims_flush_sonly_w), |
---|
1617 | .clk (clk), |
---|
1618 | .se (se), .si(), .so()); |
---|
1619 | assign ims_flush_coll_w = ims_flush_sonly_w & ~canthr_sw; |
---|
1620 | assign flush_sonly_qual_m = (ims_flush_sonly_m & ~canthr_sm & |
---|
1621 | ~retract_iferr_e | |
---|
1622 | flush_sonly_m & inst_vld_m & ~kill_local_m & |
---|
1623 | ~kill_curr_m); |
---|
1624 | assign flush_sonly_all_m = (ims_flush_sonly_m & ~canthr_sm | |
---|
1625 | flush_sonly_m & inst_vld_m); |
---|
1626 | |
---|
1627 | // assign flush_sonly_qual_m = flush_sonly_m & ~canthr_sm; |
---|
1628 | // assign qtrap_flush_e = dtu_fcl_qtrap_e & inst_vld_e & ~dtu_inst_anull_e & |
---|
1629 | // ~rb_stg_e; |
---|
1630 | |
---|
1631 | //------------------------------ |
---|
1632 | // Instruction Kill Logic |
---|
1633 | //------------------------------ |
---|
1634 | |
---|
1635 | // kill_s2 is the same as kill_f |
---|
1636 | assign kill_thread_s2 = thr_match_fw & rb_stg_w | |
---|
1637 | // thr_match_ft & trappc_vld_w2 | |
---|
1638 | thr_match_fm & (flush_sonly_all_m) | |
---|
1639 | kill_curr_f; |
---|
1640 | |
---|
1641 | assign ely_kill_thread_s2 = thr_match_fw & utrap_flush_w | |
---|
1642 | // thr_match_ft & trappc_vld_w2 | |
---|
1643 | thr_match_fm & (flush_sonly_all_m) | |
---|
1644 | kill_curr_f; |
---|
1645 | |
---|
1646 | assign kill_thread_d = thr_match_dw & rb_stg_w | |
---|
1647 | thr_match_dm & (flush_sonly_all_m) | |
---|
1648 | kill_curr_d; |
---|
1649 | |
---|
1650 | // M and E still need full qualification with flush pipe |
---|
1651 | // assign kill_thread_e = thr_match_ew & utrap_flush_w | |
---|
1652 | // thr_match_ew & tlu_ifu_flush_pipe_w | |
---|
1653 | // kill_curr_e ; |
---|
1654 | assign ely_kill_thread_m = thr_match_mw & utrap_flush_w | |
---|
1655 | // mark4rb_m | |
---|
1656 | kill_curr_m; |
---|
1657 | assign kill_thread_m = ely_kill_thread_m | |
---|
1658 | thr_match_mw & tlu_ifu_flush_pipe_w; |
---|
1659 | |
---|
1660 | assign kill_local_m = thr_match_mw & (utrap_flush_w | intr_vld_w); |
---|
1661 | |
---|
1662 | assign flush_pipe_w = rb_stg_w | tlu_ifu_flush_pipe_w; |
---|
1663 | // assign part_flush_w = ifu_tlu_flush_w | tlu_ifu_flush_pipe_w; |
---|
1664 | // assign kill_nextthr_w = thr_match_nw & flush_pipe_w; |
---|
1665 | assign flush_thr_w = thr_w & {4{flush_pipe_w}}; |
---|
1666 | dff_s #(1) fp_ff(.din (flush_pipe_w), |
---|
1667 | .q (flush_pipe_w2), |
---|
1668 | .clk (clk), .se(se), .si(), .so()); |
---|
1669 | |
---|
1670 | // assign clear_s_stage = thr_e & {4{flush_sonly_qual_e}}; |
---|
1671 | // assign clear_s_stage = trap_thr & {4{trappc_vld_w2}} | |
---|
1672 | // {4{dummy_flush_ireg}} | |
---|
1673 | // thr_e & {4{flush_sonly_qual_e}}; |
---|
1674 | // | flush_thr_w |
---|
1675 | |
---|
1676 | assign canthr_f = thr_e & {4{flush_sonly_qual_e}} | |
---|
1677 | (rb_w2 & ~rb_for_iferr_e) | rb_froms; |
---|
1678 | |
---|
1679 | // dff #(4) cls_reg(.din (clear_s_stage), |
---|
1680 | // .q (clear_s_early), |
---|
1681 | // .clk (clk), .se(se), .si(), .so()); |
---|
1682 | |
---|
1683 | // ***NOTE*** |
---|
1684 | // Don't use clear_s_d1 to generate fcl_ifq_canthr, since clear_s_d1 |
---|
1685 | // includes ifeterr! |
---|
1686 | // first term could be just flush_sonly_m & inst_vld_m & thr_m |
---|
1687 | assign clear_s_d1 = thr_m & {4{flush_sonly_all_m}} | |
---|
1688 | late_flush_w2 | |
---|
1689 | trap_thr & {4{trappc_vld_w2}}; |
---|
1690 | |
---|
1691 | assign fcl_erb_clear_iferr = thr_m & {4{ims_flush_sonly_m | |
---|
1692 | flush_sonly_m}} | |
---|
1693 | late_flush_w2 | |
---|
1694 | trap_thr & {4{trappc_vld_w2}}; |
---|
1695 | |
---|
1696 | |
---|
1697 | dff_s #(4) cm_reg(.din (canthr_f), |
---|
1698 | .q (canthr_s_early), |
---|
1699 | .clk (clk), |
---|
1700 | .se (se), .si(), .so()); |
---|
1701 | |
---|
1702 | assign canthr_s = canthr_s_early | late_flush_w2 | |
---|
1703 | trap_thr & {4{trappc_vld_w2}}; |
---|
1704 | |
---|
1705 | // assign fcl_ifq_canthr = clear_s_stage | rb_w2 | rb_froms | |
---|
1706 | // canthr_s; |
---|
1707 | assign fcl_ifq_canthr = canthr_s; |
---|
1708 | |
---|
1709 | assign canthr_sm = (canthr_s[0] & thr_m[0] | |
---|
1710 | canthr_s[1] & thr_m[1] | |
---|
1711 | canthr_s[2] & thr_m[2] | |
---|
1712 | canthr_s[3] & thr_m[3]); |
---|
1713 | |
---|
1714 | assign canthr_sw = (canthr_s[0] & thr_w[0] | |
---|
1715 | canthr_s[1] & thr_w[1] | |
---|
1716 | canthr_s[2] & thr_w[2] | |
---|
1717 | canthr_s[3] & thr_w[3]); |
---|
1718 | |
---|
1719 | assign canthr_sd = (canthr_s[0] & thr_d[0] | |
---|
1720 | canthr_s[1] & thr_d[1] | |
---|
1721 | canthr_s[2] & thr_d[2] | |
---|
1722 | canthr_s[3] & thr_d[3]) | |
---|
1723 | thr_match_dw & utrap_flush_w; |
---|
1724 | |
---|
1725 | dff_s #(4) fpw2_reg(.din (flush_thr_w), |
---|
1726 | .q (late_flush_w2), |
---|
1727 | .clk (clk), .se(se), .si(), .so()); |
---|
1728 | |
---|
1729 | // assign late_flush_w2 = thr_w2 & {4{flush_pipe_w2}}; |
---|
1730 | |
---|
1731 | assign kill_curr_f = (thr_f_crit[0] & late_flush_w2[0] | |
---|
1732 | thr_f_crit[1] & late_flush_w2[1] | |
---|
1733 | thr_f_crit[2] & late_flush_w2[2] | |
---|
1734 | thr_f_crit[3] & late_flush_w2[3]); |
---|
1735 | assign kill_curr_d = (thr_d[0] & late_flush_w2[0] | |
---|
1736 | thr_d[1] & late_flush_w2[1] | |
---|
1737 | thr_d[2] & late_flush_w2[2] | |
---|
1738 | thr_d[3] & late_flush_w2[3]); |
---|
1739 | assign kill_curr_e = (thr_e_v2[0] & late_flush_w2[0] | |
---|
1740 | thr_e_v2[1] & late_flush_w2[1] | |
---|
1741 | thr_e_v2[2] & late_flush_w2[2] | |
---|
1742 | thr_e_v2[3] & late_flush_w2[3]) | |
---|
1743 | thr_match_ew & utrap_flush_w; |
---|
1744 | |
---|
1745 | // assign kill_curr_m = (thr_m[0] & late_flush_w2[0] | |
---|
1746 | // thr_m[1] & late_flush_w2[1] | |
---|
1747 | // thr_m[2] & late_flush_w2[2] | |
---|
1748 | // thr_m[3] & late_flush_w2[3]); |
---|
1749 | assign kill_curr_m = same_thr_mw2 & flush_pipe_w2; |
---|
1750 | |
---|
1751 | //------------------------------ |
---|
1752 | // track I$ misses |
---|
1753 | //------------------------------ |
---|
1754 | |
---|
1755 | // force a miss if a fetch and icache is off |
---|
1756 | // forcemiss triggers a fill vld_grequest to L2, so set to zero by default |
---|
1757 | assign forcemiss_f = inst_vld_f & ~icache_on_f; |
---|
1758 | dffr_s #(1) miss_ff(.din (forcemiss_f), |
---|
1759 | .clk (clk), |
---|
1760 | .rst (fcl_reset), |
---|
1761 | .q (forcemiss_s1), |
---|
1762 | .se (se), .si(), .so()); |
---|
1763 | |
---|
1764 | //ooooooooooooooooooooooooooooooooooooooooooooooooooooooo |
---|
1765 | // removed imiss_s_l from this signal for timing fix |
---|
1766 | // Perf Hit: 0.2% TPCC, 0.4% JBB |
---|
1767 | // assign ic_miss_sw_s1 = (~itlb_fcl_imiss_s_l & rdreq_s1 | |
---|
1768 | // tlb_cam_miss_s1 | |
---|
1769 | // forcemiss_s1); |
---|
1770 | // assign ic_miss_sw_s1 = tlb_cam_miss_s1 | |
---|
1771 | // forcemiss_s1; |
---|
1772 | //ooooooooooooooooooooooooooooooooooooooooooooooooooooooo |
---|
1773 | |
---|
1774 | assign ic_miss_s1 = (~itlb_fcl_imiss_s_l & rdreq_s1 | |
---|
1775 | forcemiss_s1) & |
---|
1776 | ~stall_s1 & ~tlbmiss_s1_crit & ~pc_oor_s1 & |
---|
1777 | ~rb_stg_d_crit & ~canthr_sd; |
---|
1778 | |
---|
1779 | assign icmiss_for_perf = (~itlb_fcl_imiss_s_l & rdreq_s1) & |
---|
1780 | ~stall_s1 & ~tlbmiss_s1_crit & ~pc_oor_s1 & |
---|
1781 | ~rb_stg_d & ~canthr_sd; |
---|
1782 | |
---|
1783 | // assign fcl_ifq_icmiss_s1 = ic_miss_s1 & ~ely_kill_thread_d; // use buffer |
---|
1784 | assign fcl_ifq_icmiss_s1 = ic_miss_s1; // use buffer |
---|
1785 | |
---|
1786 | // for perf counters (d1=e) |
---|
1787 | dff_s #(1) icmd1_ff(.din (icmiss_for_perf), |
---|
1788 | .q (ifu_tlu_icmiss_e), |
---|
1789 | .clk (clk), .se(se), .si(), .so()); |
---|
1790 | |
---|
1791 | // I$ miss is always to thr_s1. Below we check to see if this is |
---|
1792 | // the same as thr_f (=thr_s2) which is the "current thread" |
---|
1793 | // assign imsto_thisthr_s1 = thr_match_fd & ic_miss_s1; |
---|
1794 | // assign imsto_nextthr_s1 = thr_match_nd & (ic_miss_s1 | tlbmiss_s1); |
---|
1795 | |
---|
1796 | assign imsto_thisthr_s1 = thr_match_fd & ic_miss_s1; |
---|
1797 | // assign imsto_nextthr_s1 = thr_match_nd & (ic_miss_sw_s1); |
---|
1798 | // assign intrto_thisthr_d = thr_match_fd & fcl_dtu_sync_intr_d; |
---|
1799 | |
---|
1800 | assign iferrto_thisthr_d1 = thr_match_fe & erb_dtu_ifeterr_d1 & |
---|
1801 | inst_vld_d1; |
---|
1802 | |
---|
1803 | |
---|
1804 | //------------------------------ |
---|
1805 | // track itlb misses |
---|
1806 | //------------------------------ |
---|
1807 | |
---|
1808 | // default to hit when camming is turned off |
---|
1809 | assign tlb_cam_miss_f = ~itlb_fcl_tlbmiss_f_l & cam_vld_f; |
---|
1810 | dff_s #(1) tlbmsf_ff(.din (tlb_cam_miss_f), |
---|
1811 | .clk (clk), |
---|
1812 | .q (tlb_cam_miss_s1), |
---|
1813 | .se (se), .si(), .so()); |
---|
1814 | |
---|
1815 | // tlb miss logic |
---|
1816 | // va hole has higher priority than immu miss |
---|
1817 | assign tlbmiss_s2 = (({4{tlbmiss_s1 & ~pc_oor_s1 & ~rb_stg_d}} & thr_s1) | |
---|
1818 | ({4{erb_fcl_itlb_ce_d1 & inst_vld_d1 & |
---|
1819 | ~rb_stg_e}} & thr_e & |
---|
1820 | (~thr_d | {4{~inst_vld_d | ~thr_match_de}})) | |
---|
1821 | ({4{immu_miss_e}} & rb_frome) | |
---|
1822 | ({4{immu_miss_d}} & rb_fromd & ~rb_frome) | // set |
---|
1823 | tlbmiss_d & (~thr_d | {4{~inst_vld_d}}) & ~rb_w2) & |
---|
1824 | ~(clear_s_d1); // reset |
---|
1825 | |
---|
1826 | // assign tlbmiss_s2 = (({4{tlbmiss_s1 & ~pc_oor_s1 & ~rb_stg_d}} & thr_s1) | |
---|
1827 | // ({4{erb_fcl_itlb_ce_d1 & inst_vld_qual_d1}} & thr_e | |
---|
1828 | // tlbmiss_d & (~thr_e | {4{~inst_vld_qual_e}}) & |
---|
1829 | // ~rb_w2) & ~(clear_s_stage); // reset |
---|
1830 | |
---|
1831 | dffr_s #(4) tlbmiss_reg(.din (tlbmiss_s2), |
---|
1832 | .q (tlbmiss_d), |
---|
1833 | .clk (clk), |
---|
1834 | .rst (fcl_reset), |
---|
1835 | .se (se), .si(), .so()); |
---|
1836 | |
---|
1837 | assign immu_fault_f = (thr_f_crit[0] & (tlbmiss_d[0] | inst_acc_vec_d[0]) | |
---|
1838 | thr_f_crit[1] & (tlbmiss_d[1] | inst_acc_vec_d[1]) | |
---|
1839 | thr_f_crit[2] & (tlbmiss_d[2] | inst_acc_vec_d[2]) | |
---|
1840 | thr_f_crit[3] & (tlbmiss_d[3] | inst_acc_vec_d[3])) & |
---|
1841 | switch_s2| |
---|
1842 | // D stage miss |
---|
1843 | (tlbmiss_s1 | pc_oor_s1) & thr_match_fs1; |
---|
1844 | // S stage miss |
---|
1845 | |
---|
1846 | assign immu_miss_crit_d = (thr_d[0] & tlbmiss_d[0] | |
---|
1847 | thr_d[1] & tlbmiss_d[1] | |
---|
1848 | thr_d[2] & tlbmiss_d[2] | |
---|
1849 | thr_d[3] & tlbmiss_d[3]); |
---|
1850 | |
---|
1851 | // TBD: move this to the E stage, post RB |
---|
1852 | assign immu_miss_d = immu_miss_crit_d & inst_vld_d | |
---|
1853 | thr_match_de & erb_fcl_itlb_ce_d1 & inst_vld_d1; |
---|
1854 | |
---|
1855 | // don't need to do this, once everyone switches to immu_miss_m |
---|
1856 | assign immu_miss_qual_d = immu_miss_d & ~kill_thread_d & |
---|
1857 | ~(immu_miss_e & thr_match_de & |
---|
1858 | inst_vld_e & ~dtu_inst_anull_e & ~rb_stg_e & |
---|
1859 | ~kill_curr_e); |
---|
1860 | |
---|
1861 | dff_s immu_misse_ff(.din (immu_miss_qual_d), |
---|
1862 | .clk (clk), |
---|
1863 | .q (immu_miss_e), |
---|
1864 | .se (se), .si(), .so()); |
---|
1865 | |
---|
1866 | |
---|
1867 | // flop this and send in M |
---|
1868 | // assign ifu_tlu_immu_miss_e = immu_miss_e & ~addr_real_e & |
---|
1869 | // inst_vld_e & ~dtu_inst_anull_e & ~rb_stg_e; |
---|
1870 | // assign ifu_tlu_immu_miss_e = 1'b0; |
---|
1871 | |
---|
1872 | // assign immu_miss_qual_e = immu_miss_e & //~addr_real_e & |
---|
1873 | // // ~(immu_miss_m & thr_match_em) & |
---|
1874 | // inst_vld_e & ~dtu_inst_anull_e & ~rb_stg_e; |
---|
1875 | |
---|
1876 | // dff #(1) immu_msm_ff(.din (immu_miss_qual_e), |
---|
1877 | dff_s #(1) immu_msm_ff(.din (immu_miss_e), |
---|
1878 | .q (immu_miss_m), |
---|
1879 | .clk (clk), .se(se), .si(), .so()); |
---|
1880 | |
---|
1881 | assign ifu_tlu_immu_miss_m = immu_miss_m & inst_vld_m & ~kill_curr_m; |
---|
1882 | |
---|
1883 | assign addr_real_e = (itlb_addr_real[0] & thr_e[0] | |
---|
1884 | itlb_addr_real[1] & thr_e[1] | |
---|
1885 | itlb_addr_real[2] & thr_e[2] | |
---|
1886 | itlb_addr_real[3] & thr_e[3]); |
---|
1887 | |
---|
1888 | // store tlbmiss state for NIR |
---|
1889 | assign nir_tlbmiss_next = ({4{tlb_cam_miss_s1 & ~stall_s1}} & thr_s1 | |
---|
1890 | nir_tlbmiss_vec & (~thr_s1 | {4{stall_s1}})); |
---|
1891 | |
---|
1892 | dffr_s #(4) nirtlbm_reg(.din (nir_tlbmiss_next), |
---|
1893 | .clk (clk), |
---|
1894 | .q (nir_tlbmiss_vec), |
---|
1895 | .rst (fcl_reset), |
---|
1896 | .se (se), .si(), .so()); |
---|
1897 | |
---|
1898 | assign nir_tlbmiss_s1 = (nir_tlbmiss_vec[0] & thr_s1[0] | |
---|
1899 | nir_tlbmiss_vec[1] & thr_s1[1] | |
---|
1900 | nir_tlbmiss_vec[2] & thr_s1[2] | |
---|
1901 | nir_tlbmiss_vec[3] & thr_s1[3]); |
---|
1902 | |
---|
1903 | assign tlbmiss_s1_crit = ~usenir_s1 ? tlb_cam_miss_s1 : |
---|
1904 | nir_tlbmiss_s1; |
---|
1905 | |
---|
1906 | assign tlbmiss_s1 = tlbmiss_s1_crit & ~stall_s1; |
---|
1907 | |
---|
1908 | //--------------------------------- |
---|
1909 | // Privilege Mode and VA Hole |
---|
1910 | //--------------------------------- |
---|
1911 | assign addr_mask_32b_m = (thr_m[0] & pstate_am_d1[0] | |
---|
1912 | thr_m[1] & pstate_am_d1[1] | |
---|
1913 | thr_m[2] & pstate_am_d1[2] | |
---|
1914 | thr_m[3] & pstate_am_d1[3]); |
---|
1915 | |
---|
1916 | assign fcl_fdp_mask32b_f = (thr_f[0] & pstate_am_d1[0] | |
---|
1917 | thr_f[1] & pstate_am_d1[1] | |
---|
1918 | thr_f[2] & pstate_am_d1[2] | |
---|
1919 | thr_f[3] & pstate_am_d1[3]); |
---|
1920 | |
---|
1921 | dff_s #(1) amd_ff(.din (fcl_fdp_mask32b_f), |
---|
1922 | .q (fcl_fdp_addr_mask_d), |
---|
1923 | .clk (clk), .se(se), .si(), .so()); |
---|
1924 | |
---|
1925 | // keep track of whether pc is outside va hole |
---|
1926 | assign set_oor_m = exu_ifu_va_oor_m & brtaken_m & ~addr_mask_32b_m; |
---|
1927 | assign fcl_fdp_pcoor_vec_f = fdp_fcl_pc_oor_vec_f | {4{set_oor_m}} & thr_m; |
---|
1928 | |
---|
1929 | assign fcl_fdp_pcoor_f = (thr_f[0] & fcl_fdp_pcoor_vec_f[0] | |
---|
1930 | thr_f[1] & fcl_fdp_pcoor_vec_f[1] | |
---|
1931 | thr_f[2] & fcl_fdp_pcoor_vec_f[2] | |
---|
1932 | thr_f[3] & fcl_fdp_pcoor_vec_f[3]); |
---|
1933 | |
---|
1934 | assign pc_oor_f = fcl_fdp_pcoor_f & ~part_stall_thisthr_f; |
---|
1935 | dff_s oors1_ff(.din (pc_oor_f), |
---|
1936 | .q (pc_oor_s1), |
---|
1937 | .clk (clk), .se(se), .si(), .so()); |
---|
1938 | |
---|
1939 | // track privilege mode of current page |
---|
1940 | assign priv_mode_f = (thr_f[0] & tlu_lsu_pstate_priv[0] | |
---|
1941 | thr_f[1] & tlu_lsu_pstate_priv[1] | |
---|
1942 | thr_f[2] & tlu_lsu_pstate_priv[2] | |
---|
1943 | thr_f[3] & tlu_lsu_pstate_priv[3]); |
---|
1944 | |
---|
1945 | dff_s #(1) priv_ff(.din (priv_mode_f), |
---|
1946 | .q (priv_mode_s1), |
---|
1947 | .clk (clk), .se(se), .si(), .so()); |
---|
1948 | |
---|
1949 | // s1 and d are the same thread |
---|
1950 | assign fcl_dtu_privmode_d = priv_mode_s1; |
---|
1951 | |
---|
1952 | // hyper privilege |
---|
1953 | assign hpriv_mode_f = (thr_f[0] & tlu_hpstate_priv[0] | |
---|
1954 | thr_f[1] & tlu_hpstate_priv[1] | |
---|
1955 | thr_f[2] & tlu_hpstate_priv[2] | |
---|
1956 | thr_f[3] & tlu_hpstate_priv[3]); |
---|
1957 | |
---|
1958 | assign hpriv_mode_w = (thr_w[0] & tlu_hpstate_priv[0] | |
---|
1959 | thr_w[1] & tlu_hpstate_priv[1] | |
---|
1960 | thr_w[2] & tlu_hpstate_priv[2] | |
---|
1961 | thr_w[3] & tlu_hpstate_priv[3]); |
---|
1962 | |
---|
1963 | dff_s #(1) hprivd_ff(.din (hpriv_mode_f), |
---|
1964 | .q (hpriv_mode_s1), |
---|
1965 | .clk (clk), .se(se), .si(), .so()); |
---|
1966 | |
---|
1967 | assign fcl_dtu_hprivmode_d = hpriv_mode_s1; |
---|
1968 | |
---|
1969 | dff_s #(1) hprivw2_ff(.din (hpriv_mode_w), |
---|
1970 | .q (hpriv_mode_w2), |
---|
1971 | .clk (clk), .se(se), .si(), .so()); |
---|
1972 | assign fcl_dtu_hprivmode_w2 = hpriv_mode_w2; |
---|
1973 | |
---|
1974 | // determine if priv page has been accessed in non priv mode |
---|
1975 | // or if we have fallen into the VA hole |
---|
1976 | assign inst_acc_exc_s1 = (priv_inst_s1 & ~(priv_mode_s1 | hpriv_mode_s1) & |
---|
1977 | ~tlbmiss_s1_crit & cam_vld_s1 | |
---|
1978 | pc_oor_s1) & ~stall_s1 & ~rb_stg_d; |
---|
1979 | assign pc_oor_s2 = (thr_f[0] & inst_acc_vec_d[0] | |
---|
1980 | thr_f[1] & inst_acc_vec_d[1] | |
---|
1981 | thr_f[2] & inst_acc_vec_d[2] | |
---|
1982 | thr_f[3] & inst_acc_vec_d[3]); |
---|
1983 | assign pc_oor_s = (tm_fd_l) ? pc_oor_s2 : pc_oor_s1; |
---|
1984 | |
---|
1985 | assign inst_acc_vec_s2 = (({4{inst_acc_exc_s1}} & thr_s1) | |
---|
1986 | ({4{inst_acc_exc_e}} & rb_frome) | |
---|
1987 | ({4{inst_acc_exc_d}} & rb_fromd & ~rb_frome) | |
---|
1988 | inst_acc_vec_d & (~thr_d | {4{~inst_vld_d}}) & |
---|
1989 | ~rb_w2) & |
---|
1990 | ~(clear_s_d1); |
---|
1991 | |
---|
1992 | dffr_s #(4) instaccd_reg(.din (inst_acc_vec_s2), |
---|
1993 | .q (inst_acc_vec_d), |
---|
1994 | .rst (fcl_reset), |
---|
1995 | .clk (clk), .se (se), .si(), .so()); |
---|
1996 | |
---|
1997 | assign inst_acc_exc_d = (thr_d[0] & inst_acc_vec_d[0] | |
---|
1998 | thr_d[1] & inst_acc_vec_d[1] | |
---|
1999 | thr_d[2] & inst_acc_vec_d[2] | |
---|
2000 | thr_d[3] & inst_acc_vec_d[3]); |
---|
2001 | |
---|
2002 | dff_s #(1) instacce_ff(.din (inst_acc_exc_d), |
---|
2003 | .q (inst_acc_exc_e), |
---|
2004 | .clk (clk), .se(se), .si(), .so()); |
---|
2005 | |
---|
2006 | // TLU needs to know if this is a priv violtn |
---|
2007 | assign priv_violtn_e = inst_acc_exc_e & ~fdp_fcl_pc_oor_e; |
---|
2008 | dff_s #(1) privm_ff(.din (priv_violtn_e), |
---|
2009 | .q (priv_violtn_m), |
---|
2010 | .clk (clk), .se (se), .si(), .so()); |
---|
2011 | |
---|
2012 | assign ifu_tlu_priv_violtn_m = priv_violtn_m & inst_vld_m & ~kill_curr_m; |
---|
2013 | |
---|
2014 | // NIR privilege bit |
---|
2015 | assign next_nir_privvec = {4{itlb_fcl_priv_s1 & ~stall_s1 & |
---|
2016 | cam_vld_s1}} & thr_s1 | |
---|
2017 | nir_privvec & (~thr_s1 | {4{stall_s1}}); |
---|
2018 | |
---|
2019 | dffr_s #(4) nir_priv_reg(.din (next_nir_privvec), |
---|
2020 | .q (nir_privvec), |
---|
2021 | .rst (fcl_reset), |
---|
2022 | .clk (clk), .se(se), .si(), .so()); |
---|
2023 | |
---|
2024 | assign nir_priv_s1 = (nir_privvec[0] & thr_s1[0] | |
---|
2025 | nir_privvec[1] & thr_s1[1] | |
---|
2026 | nir_privvec[2] & thr_s1[2] | |
---|
2027 | nir_privvec[3] & thr_s1[3]); |
---|
2028 | |
---|
2029 | assign priv_inst_s1 = ~usenir_s1 ? (itlb_fcl_priv_s1 & cam_vld_s1) : |
---|
2030 | nir_priv_s1; |
---|
2031 | |
---|
2032 | //------------------------- |
---|
2033 | // Errors |
---|
2034 | //------------------------- |
---|
2035 | |
---|
2036 | // decide when the errors are valid |
---|
2037 | assign running_s1 = ~stall_s1 & ~kill_thread_d & ~rb_stg_d & ~pc_oor_s1 & |
---|
2038 | ~tlb_cam_miss_s1 & ~retract_inst_d; |
---|
2039 | // assign ely_running_s1 = ~stall_s1 & ~rb_stg_d & ~pc_oor_s1 & |
---|
2040 | // ~tlb_cam_miss_s1 & ~retract_inst_d & ~kill_curr_d; |
---|
2041 | assign ely_running_s1 = ~stall_s1 & ~rb_stg_d_crit & ~pc_oor_s1 & |
---|
2042 | ~tlb_cam_miss_s1 & ~kill_curr_d; |
---|
2043 | assign fcl_erb_ievld_s1 = ely_running_s1 & rdreq_s1 & itlb_fcl_imiss_s_l; |
---|
2044 | assign fcl_erb_tevld_s1 = ely_running_s1 & rdreq_s1; |
---|
2045 | |
---|
2046 | assign fcl_erb_immuevld_s1 = ely_running_s1 & cam_vld_s1; |
---|
2047 | |
---|
2048 | // assign fcl_erb_ttevld_s1 = asird_s & rdtag_s; |
---|
2049 | // assign fcl_erb_tdevld_s1 = asird_s & ~rdtag_s; |
---|
2050 | |
---|
2051 | dff_s #(1) d1vld_ff(.din (running_s1), |
---|
2052 | .q (inst_vld_d1), |
---|
2053 | .clk (clk), .se(se), .si(), .so()); |
---|
2054 | // assign inst_vld_qual_d1 = inst_vld_d1 & ~kill_thread_e & |
---|
2055 | // ~flush_sonly_qual_e & ~rb_stg_e; |
---|
2056 | assign fcl_erb_inst_vld_d1 = inst_vld_d1; |
---|
2057 | |
---|
2058 | |
---|
2059 | // ifetch unc. error |
---|
2060 | assign ifet_ue_vec_d1 = (erb_fcl_ifet_uevec_d1 | |
---|
2061 | ifet_ue_vec_e & ~val_thr_e) & // reset |
---|
2062 | ~(clear_s_d1); // wins |
---|
2063 | |
---|
2064 | dffr_s #(4) ifuerr_reg(.din (ifet_ue_vec_d1), |
---|
2065 | .q (ifet_ue_vec_e), |
---|
2066 | .rst (fcl_reset), |
---|
2067 | .clk (clk), .se(se), .si(), .so()); |
---|
2068 | |
---|
2069 | assign ifet_ue_e = (ifet_ue_vec_e[0] & thr_e[0] | |
---|
2070 | ifet_ue_vec_e[1] & thr_e[1] | |
---|
2071 | ifet_ue_vec_e[2] & thr_e[2] | |
---|
2072 | ifet_ue_vec_e[3] & thr_e[3]); |
---|
2073 | |
---|
2074 | |
---|
2075 | //---------------------- |
---|
2076 | // Other I side traps |
---|
2077 | //---------------------- |
---|
2078 | // Determine if we are in Trap Level 0 |
---|
2079 | assign tlzero_s2 = (thr_f[0] & tlzero_vec_d1[0] | |
---|
2080 | thr_f[1] & tlzero_vec_d1[1] | |
---|
2081 | thr_f[2] & tlzero_vec_d1[2] | |
---|
2082 | thr_f[3] & tlzero_vec_d1[3]); |
---|
2083 | dff_s #(1) tlzd_ff(.din (tlzero_s2), |
---|
2084 | .q (fcl_dtu_tlzero_d), |
---|
2085 | .clk (clk), .se(se), .si(), .so()); |
---|
2086 | |
---|
2087 | // Collect all IFU traps |
---|
2088 | assign trap_e = (immu_miss_e | inst_acc_exc_e | dtu_fcl_illinst_e | |
---|
2089 | dtu_fcl_fpdis_e | dtu_fcl_privop_e | ifet_ue_e | |
---|
2090 | dtu_fcl_imask_hit_e | dtu_fcl_sir_inst_e) & |
---|
2091 | inst_vld_e; |
---|
2092 | |
---|
2093 | dff_s trapm_ff(.din (trap_e), |
---|
2094 | .q (trap_m), |
---|
2095 | .clk (clk), |
---|
2096 | .se (se), .si(), .so()); |
---|
2097 | |
---|
2098 | assign no_iftrap_m = ~ifu_tlu_ttype_vld_m; |
---|
2099 | dff_s trapw_ff(.din (no_iftrap_m), |
---|
2100 | .q (no_iftrap_w), |
---|
2101 | .clk (clk), |
---|
2102 | .se (se), .si(), .so()); |
---|
2103 | |
---|
2104 | // south is very critical |
---|
2105 | assign ifu_tlu_ttype_vld_m = (trap_m & inst_vld_m | |
---|
2106 | disr_trap_m) & ~kill_curr_m & ~kill_local_m; |
---|
2107 | // less critical going east |
---|
2108 | assign ifu_exu_ttype_vld_m = trap_m & inst_vld_m; |
---|
2109 | |
---|
2110 | // less critical going southwest |
---|
2111 | assign ifu_mmu_trap_m = trap_m; |
---|
2112 | |
---|
2113 | // less critical going south |
---|
2114 | assign ifu_tlu_trap_m = trap_m; |
---|
2115 | |
---|
2116 | // trap type priority encode |
---|
2117 | // Decreasing priority is |
---|
2118 | // pc out of range i_acc_exc |
---|
2119 | // immu parity error i_acc_err |
---|
2120 | // immu miss i_acc_mmu_ms |
---|
2121 | // icache/tag parity error i_acc_err |
---|
2122 | // privilege page i_acc_exc |
---|
2123 | // privilege opcode priv_opc |
---|
2124 | // illegal non-fp inst ill_inst |
---|
2125 | // soft reset sir |
---|
2126 | // fp disabled fp_disabled |
---|
2127 | // illegal fp instruction ill_inst |
---|
2128 | |
---|
2129 | // Clean this up!! |
---|
2130 | assign ttype_sel_spuma_e = spuint1_qual_e; |
---|
2131 | assign ttype_sel_spuenc_e = spuint0_qual_e; |
---|
2132 | assign ttype_sel_corr_err_e = ceint_qual_e; |
---|
2133 | assign ttype_sel_unc_err_e = ueint_qual_e; |
---|
2134 | assign ttype_sel_res_err_e = rerr_qual_e; |
---|
2135 | assign ttype_sel_hstk_cmp_e = hintp_qual_e; |
---|
2136 | |
---|
2137 | assign ttype_sel_pcoor_e = fdp_fcl_pc_oor_e & inst_acc_exc_e; |
---|
2138 | assign ttype_sel_icache_err_e = ifet_ue_e; |
---|
2139 | assign ttype_sel_immu_miss_e = ~fdp_fcl_pc_oor_e & immu_miss_e & |
---|
2140 | ~addr_real_e; |
---|
2141 | assign ttype_sel_real_trans_e = ~fdp_fcl_pc_oor_e & immu_miss_e & |
---|
2142 | addr_real_e; |
---|
2143 | assign ttype_sel_priv_viol_e = ~fdp_fcl_pc_oor_e & ~immu_miss_e & |
---|
2144 | inst_acc_exc_e; |
---|
2145 | assign ttype_sel_ibe_e = ~fdp_fcl_pc_oor_e & ~immu_miss_e & |
---|
2146 | ~inst_acc_exc_e & dtu_fcl_imask_hit_e; |
---|
2147 | assign ttype_sel_privop_e = ~fdp_fcl_pc_oor_e & ~immu_miss_e & |
---|
2148 | ~inst_acc_exc_e & dtu_fcl_privop_e; |
---|
2149 | assign ttype_sel_illinst_e = ~fdp_fcl_pc_oor_e & ~immu_miss_e & |
---|
2150 | ~inst_acc_exc_e & dtu_fcl_illinst_e; |
---|
2151 | assign ttype_sel_sir_e = ~fdp_fcl_pc_oor_e & ~immu_miss_e & |
---|
2152 | ~inst_acc_exc_e & ~dtu_fcl_illinst_e & |
---|
2153 | dtu_fcl_sir_inst_e; |
---|
2154 | |
---|
2155 | assign ttype_sel_fpdis_e = ~fdp_fcl_pc_oor_e & ~immu_miss_e & |
---|
2156 | ~inst_acc_exc_e & ~dtu_fcl_illinst_e & |
---|
2157 | dtu_fcl_fpdis_e; |
---|
2158 | |
---|
2159 | // mux in the trap type |
---|
2160 | assign ttype_e[8:0] = ttype_sel_unc_err_e ? `DATA_ERR : |
---|
2161 | ttype_sel_hstk_cmp_e ? `HSTICK_CMP : |
---|
2162 | ttype_sel_spuma_e ? `SPU_MAINT : |
---|
2163 | ttype_sel_spuenc_e ? `SPU_ENCINT : |
---|
2164 | ttype_sel_corr_err_e ? `CORR_ECC_ERR : |
---|
2165 | ttype_sel_res_err_e ? `RESUMABLE_ERR : |
---|
2166 | |
---|
2167 | ttype_sel_pcoor_e ? `INST_ACC_EXC : |
---|
2168 | ttype_sel_immu_miss_e ? `FAST_MMU_MS : |
---|
2169 | ttype_sel_real_trans_e ? `REAL_TRANS_MS : |
---|
2170 | ttype_sel_icache_err_e ? `INST_ACC_ERR : |
---|
2171 | ttype_sel_priv_viol_e ? `INST_ACC_EXC : |
---|
2172 | ttype_sel_ibe_e ? `INST_BRK_PT : |
---|
2173 | ttype_sel_privop_e ? `PRIV_OPC : |
---|
2174 | ttype_sel_illinst_e ? `ILL_INST : |
---|
2175 | ttype_sel_sir_e ? `SIR : |
---|
2176 | ttype_sel_fpdis_e ? `FP_DISABLED : |
---|
2177 | 9'h1ff; |
---|
2178 | |
---|
2179 | dff_s #(9) ttype_reg(.din (ttype_e[8:0]), |
---|
2180 | .q (ifu_tlu_ttype_m[8:0]), |
---|
2181 | .clk (clk), .se(se), .si(), .so()); |
---|
2182 | |
---|
2183 | //------------------------------ |
---|
2184 | // Interrupts and Resets |
---|
2185 | //------------------------------ |
---|
2186 | // Process resets to see if they are sync or async |
---|
2187 | assign intr_in_pipe = ({4{intr_vld_d}} & thr_d | |
---|
2188 | {4{intr_vld_e}} & thr_e | |
---|
2189 | {4{intr_vld_m}} & thr_m | |
---|
2190 | {4{intr_vld_w}} & thr_w); |
---|
2191 | |
---|
2192 | // assign async_rst_i2 = tlu_ifu_rstthr_i2 & {4{tlu_ifu_rstint_i2}} & |
---|
2193 | assign async_rst_i3 = (rstint_i3 | nuke_thr_i3 | resumint_i3) & |
---|
2194 | ~dtu_fcl_thr_active & ~intr_in_pipe; |
---|
2195 | |
---|
2196 | dff_s #(4) asyrst4_reg(.din (async_rst_i3), |
---|
2197 | .q (async_rst_i4), |
---|
2198 | .clk (clk), .se(se), .si(), .so()); |
---|
2199 | |
---|
2200 | // stall pipe before switching in rst thread |
---|
2201 | assign rst_stallreq_d0 = (|async_rst_i4[3:0]); |
---|
2202 | assign rst_stallreq = rst_stallreq_d0 | rst_stallreq_d1 | rst_stallreq_d2; |
---|
2203 | |
---|
2204 | dff_s #(2) stlreq_reg(.din ({lsu_ifu_stallreq, |
---|
2205 | ffu_ifu_stallreq}), |
---|
2206 | .q ({lsu_stallreq_d1, |
---|
2207 | ffu_stallreq_d1}), |
---|
2208 | .clk (clk), .se(se), .si(), .so()); |
---|
2209 | |
---|
2210 | assign all_stallreq = ifq_fcl_stallreq | lsu_stallreq_d1 | |
---|
2211 | ffu_stallreq_d1 | itlb_starv_alert; |
---|
2212 | |
---|
2213 | // leave out stall from ifq which goes directly to swl |
---|
2214 | assign fcl_dtu_stall_bf = lsu_stallreq_d1 | ffu_stallreq_d1 | |
---|
2215 | itlb_starv_alert | rst_stallreq; |
---|
2216 | |
---|
2217 | // priority encode rst interrupts |
---|
2218 | // this could lead to obvious starvation of thr3, the assumption is that |
---|
2219 | // idle/resume/reset interrupts do not occur very frequently |
---|
2220 | assign rstint_penc[0] = async_rst_i4[0]; |
---|
2221 | assign rstint_penc[1] = ~async_rst_i4[0] & async_rst_i4[1]; |
---|
2222 | assign rstint_penc[2] = ~async_rst_i4[0] & ~async_rst_i4[1] & |
---|
2223 | async_rst_i4[2]; |
---|
2224 | assign rstint_penc[3] = ~async_rst_i4[0] & ~async_rst_i4[1] & |
---|
2225 | ~async_rst_i4[2]; |
---|
2226 | |
---|
2227 | // BF - switch in rst thread |
---|
2228 | dff_s #(1) asyncr1_ff(.din (rst_stallreq_d0), |
---|
2229 | .q (rst_stallreq_d1), |
---|
2230 | .clk (clk), .se(se), .si(), .so()); |
---|
2231 | assign arst_vld_f_l = ~arst_vld_f; |
---|
2232 | assign arst_vld_s_l = ~arst_vld_s; |
---|
2233 | bw_u1_nand3_4x UZsize_rstsw_n3(.z (rst_sw_bf_l), |
---|
2234 | .a (arst_vld_f_l), |
---|
2235 | .b (arst_vld_s_l), |
---|
2236 | .c (rst_stallreq_d1)); |
---|
2237 | assign rst_sw_bf = ~rst_sw_bf_l; |
---|
2238 | |
---|
2239 | // double check if asyn intrs are still valid |
---|
2240 | assign sw_for_real_rst_bf = rst_sw_bf & rst_stallreq_d0; |
---|
2241 | |
---|
2242 | // F |
---|
2243 | dff_s #(1) asyncr2_ff(.din (sw_for_real_rst_bf), |
---|
2244 | .q (rst_stallreq_d2), |
---|
2245 | .clk (clk), .se(se), .si(), .so()); |
---|
2246 | // assign arst_vld_f = rst_stallreq_d2 & any_rstnuke_f; |
---|
2247 | assign arst_vld_f = rst_stallreq_d2; |
---|
2248 | |
---|
2249 | // hold thread till reset of curr thread is processed |
---|
2250 | // assign rst_thr_bf = arst_vld_f ? thr_f : rstint_penc; |
---|
2251 | |
---|
2252 | // S issue to pipe |
---|
2253 | dff_s #(1) rstvlds_ff(.din (arst_vld_f), |
---|
2254 | .q (arst_vld_s), |
---|
2255 | .clk (clk), .se(se), .si(), .so()); |
---|
2256 | assign async_intr_vld_s = arst_vld_s & ~kill_intr_f; // & any_rstnuke_f |
---|
2257 | |
---|
2258 | |
---|
2259 | // |
---|
2260 | // thread wise interrupts |
---|
2261 | // |
---|
2262 | assign rstint_i2 = {4{tlu_ifu_rstint_i2}} & tlu_ifu_rstthr_i2; |
---|
2263 | assign resumint_i2 = {4{tlu_ifu_resumint_i2}} & tlu_ifu_rstthr_i2; |
---|
2264 | assign nuke_thr_i2 = {4{tlu_ifu_nukeint_i2}} & tlu_ifu_rstthr_i2; |
---|
2265 | |
---|
2266 | assign next_rst_i2 = rstint_i2 | |
---|
2267 | rstint_i3 & (~(thr_w & {4{fcl_dtu_rst_thr_w}})); |
---|
2268 | assign next_resum_i2 = resumint_i2 | |
---|
2269 | resumint_i3 & (~(thr_w & {4{fcl_dtu_resum_thr_w}})) |
---|
2270 | & ~rstint_i2; |
---|
2271 | |
---|
2272 | assign next_nuke_i2 = (nuke_thr_i2 | nuke_thr_i3) & |
---|
2273 | (~(thr_w & {4{fcl_dtu_nuke_thr_w}})) & |
---|
2274 | ~(rstint_i2 | resumint_i2); |
---|
2275 | |
---|
2276 | assign next_sftint_i2 = tlu_ifu_sftint_vld; |
---|
2277 | assign next_hwint_i3 = tlu_ifu_hwint_i3; |
---|
2278 | assign next_hintp_i2 = tlu_ifu_hintp_vld; |
---|
2279 | assign next_rerr_i2 = tlu_ifu_rerr_vld; |
---|
2280 | |
---|
2281 | assign next_ceint_i2 = erb_fcl_ce_trapvec | |
---|
2282 | ceint_i3 & (~(thr_w & {4{ceint_qual_w}})); |
---|
2283 | |
---|
2284 | assign next_ueint_i2 = erb_fcl_ue_trapvec | |
---|
2285 | ueint_i3 & (~(thr_w & {4{ueint_qual_w}})); |
---|
2286 | |
---|
2287 | // From Farnad: tid is ready several cycles before everything else |
---|
2288 | // I will assume 1 cycle before in the ifu |
---|
2289 | dff_s #(2) sptid_reg(.din (spu_ifu_ttype_tid_w2), |
---|
2290 | .q (spu_tid_w2), |
---|
2291 | .clk (clk), .se(se), .so(), .si()); |
---|
2292 | |
---|
2293 | assign spu_thr[0] = ~spu_tid_w2[1] & ~spu_tid_w2[0]; |
---|
2294 | assign spu_thr[1] = ~spu_tid_w2[1] & spu_tid_w2[0]; |
---|
2295 | assign spu_thr[2] = spu_tid_w2[1] & ~spu_tid_w2[0]; |
---|
2296 | assign spu_thr[3] = spu_tid_w2[1] & spu_tid_w2[0]; |
---|
2297 | |
---|
2298 | assign next_spuint1_i2 = {4{spu_ifu_ttype_vld_w2 & spu_ifu_ttype_w2}} & |
---|
2299 | spu_thr & ~erb_fcl_spu_uetrap | |
---|
2300 | spuint1_i3 & ~({4{spuint1_w}} & thr_w); |
---|
2301 | |
---|
2302 | assign next_spuint0_i2 = {4{spu_ifu_ttype_vld_w2 & ~spu_ifu_ttype_w2}} & |
---|
2303 | spu_thr & ~erb_fcl_spu_uetrap | |
---|
2304 | spuint0_i3 & ~({4{spuint0_w}} & thr_w); |
---|
2305 | |
---|
2306 | |
---|
2307 | dffr_s #(4) rst_reg(.din (next_rst_i2), |
---|
2308 | .q (rstint_i3), |
---|
2309 | .clk (clk), |
---|
2310 | .rst (fcl_reset), |
---|
2311 | .se (se), .si(), .so()); |
---|
2312 | |
---|
2313 | dffr_s #(4) resum_reg(.din (next_resum_i2), |
---|
2314 | .q (resumint_i3), |
---|
2315 | .clk (clk), |
---|
2316 | .rst (fcl_reset), |
---|
2317 | .se (se), .si(), .so()); |
---|
2318 | |
---|
2319 | dffr_s #(4) nuke_reg(.din (next_nuke_i2), |
---|
2320 | .q (nuke_thr_i3), |
---|
2321 | .rst (fcl_reset), |
---|
2322 | .clk (clk), |
---|
2323 | .se (se), .si(), .so()); |
---|
2324 | |
---|
2325 | dffr_s #(4) sfti_reg(.din (next_sftint_i2), |
---|
2326 | .q (sftint_i3), |
---|
2327 | .rst (fcl_reset), |
---|
2328 | .clk (clk), .se (se), .si(), .so()); |
---|
2329 | dffr_s #(4) hstki_reg(.din (next_hintp_i2), |
---|
2330 | .q (hintp_i3), |
---|
2331 | .rst (fcl_reset), |
---|
2332 | .clk (clk), .se (se), .si(), .so()); |
---|
2333 | dffr_s #(4) reri_reg(.din (next_rerr_i2), |
---|
2334 | .q (rerr_i3), |
---|
2335 | .rst (fcl_reset), |
---|
2336 | .clk (clk), .se (se), .si(), .so()); |
---|
2337 | dffr_s #(4) hwi_reg(.din (next_hwint_i3), |
---|
2338 | .q (hwint_i4), |
---|
2339 | .rst (fcl_reset), |
---|
2340 | .clk (clk), .se (se), .si(), .so()); |
---|
2341 | |
---|
2342 | dffr_s #(4) spui0_reg(.din (next_spuint0_i2), |
---|
2343 | .q (spuint0_i3), |
---|
2344 | .rst (fcl_reset), |
---|
2345 | .clk (clk), .se (se), .si(), .so()); |
---|
2346 | |
---|
2347 | dffr_s #(4) spui1_reg(.din (next_spuint1_i2), |
---|
2348 | .q (spuint1_i3), |
---|
2349 | .rst (fcl_reset), |
---|
2350 | .clk (clk), .se (se), .si(), .so()); |
---|
2351 | |
---|
2352 | dffr_s #(4) cei_reg(.din (next_ceint_i2), |
---|
2353 | .q (ceint_i3), |
---|
2354 | .rst (fcl_reset), |
---|
2355 | .clk (clk), .se (se), .si(), .so()); |
---|
2356 | |
---|
2357 | dffr_s #(4) uei_reg(.din (next_ueint_i2), |
---|
2358 | .q (ueint_i3), |
---|
2359 | .rst (fcl_reset), |
---|
2360 | .clk (clk), .se (se), .si(), .so()); |
---|
2361 | |
---|
2362 | assign supv_int_en = (~tlu_hpstate_priv | ~tlu_hpstate_enb) & |
---|
2363 | tlu_ifu_pstate_ie & dtu_fcl_thr_active; |
---|
2364 | assign hypv_int_en = ~tlu_hpstate_priv & tlu_hpstate_enb | |
---|
2365 | tlu_ifu_pstate_ie & dtu_fcl_thr_active; |
---|
2366 | |
---|
2367 | dff_s #(4) spvie_ff(.din (supv_int_en), |
---|
2368 | .q (supv_int_en_d1), |
---|
2369 | .clk (clk), .se(se), .si(), .so()); |
---|
2370 | dff_s #(4) hpvie_ff(.din (hypv_int_en), |
---|
2371 | .q (hypv_int_en_d1), |
---|
2372 | .clk (clk), .se(se), .si(), .so()); |
---|
2373 | |
---|
2374 | // force an interrupt by putting nop on pipe |
---|
2375 | // use this signal instead of hw_int_s to help with crit path |
---|
2376 | assign supv_masked_intr_s = (sftint_i3 | |
---|
2377 | rerr_i3); |
---|
2378 | assign hypv_masked_intr_s = (hwint_i4 | |
---|
2379 | hintp_i3 | |
---|
2380 | ceint_i3 | |
---|
2381 | ueint_i3 | |
---|
2382 | spuint0_i3 | |
---|
2383 | spuint1_i3); |
---|
2384 | |
---|
2385 | assign fcl_swl_int_activate_i3 = hypv_masked_intr_s | |
---|
2386 | supv_masked_intr_s; |
---|
2387 | |
---|
2388 | // keep track of rolled back interrupts |
---|
2389 | assign intr_pending_nxt = (({4{intr_vld_e}} & rb_frome) | |
---|
2390 | ({4{intr_vld_d}} & rb_fromd & ~rb_frome) | |
---|
2391 | intr_pending_s) & ~clear_s_d1; |
---|
2392 | |
---|
2393 | dffr_s #(4) ipend_reg(.din (intr_pending_nxt), |
---|
2394 | .q (intr_pending_s), |
---|
2395 | .rst (fcl_reset), |
---|
2396 | .clk (clk), .se(se), .si(), .so()); |
---|
2397 | |
---|
2398 | assign any_intr_vec_f = (supv_masked_intr_s & supv_int_en_d1 | |
---|
2399 | hypv_masked_intr_s & hypv_int_en_d1 | |
---|
2400 | intr_pending_s | |
---|
2401 | rstint_i3 | |
---|
2402 | resumint_i3 | |
---|
2403 | nuke_thr_i3); |
---|
2404 | |
---|
2405 | dff_s #(4) anyints_reg(.din (any_intr_vec_f), |
---|
2406 | .q (any_intr_vec_s), |
---|
2407 | .clk (clk), .se(se), .si(), .so()); |
---|
2408 | |
---|
2409 | assign force_intr_s = (thr_f_crit[0] & any_intr_vec_s[0] | |
---|
2410 | thr_f_crit[1] & any_intr_vec_s[1] | |
---|
2411 | thr_f_crit[2] & any_intr_vec_s[2] | |
---|
2412 | thr_f_crit[3] & any_intr_vec_s[3]) & |
---|
2413 | ~kill_intr_f; |
---|
2414 | |
---|
2415 | // interrupt and reset signal pipe |
---|
2416 | // VA hole trap has higher priority than interrupt |
---|
2417 | // - since the VA hole marker is lost once the intr is taken |
---|
2418 | assign intr_vld_s = force_intr_s & (valid_s & ~pc_oor_s | |
---|
2419 | async_intr_vld_s); |
---|
2420 | |
---|
2421 | assign intr_vld_qual_s = intr_vld_s & ~iferrto_thisthr_d1; |
---|
2422 | dff_s #(1) any_intrd_ff(.din (intr_vld_qual_s), |
---|
2423 | .q (intr_vld_d), |
---|
2424 | .clk (clk), |
---|
2425 | .se (se), .so(), .si()); |
---|
2426 | assign fcl_dec_intr_vld_d = intr_vld_d; |
---|
2427 | assign intr_vld_qual_d = intr_vld_d & ~kill_intr_d & ~kill_thread_d & |
---|
2428 | ~rb_stg_d; |
---|
2429 | |
---|
2430 | dff_s #(1) intr_vlde_ff(.din (intr_vld_qual_d), |
---|
2431 | .q (intr_vld_e), |
---|
2432 | .clk (clk), .se (se), .so(), .si()); |
---|
2433 | |
---|
2434 | assign intr_vld_qual_e = intr_vld_e & ~kill_curr_e & ~rb_stg_e & |
---|
2435 | ~kill_intr_e & ~dtu_inst_anull_e & |
---|
2436 | ~(thr_match_em & ifu_tlu_flush_m); |
---|
2437 | |
---|
2438 | dff_s #(1) intr_vldm_ff(.din (intr_vld_qual_e), |
---|
2439 | .q (intr_vld_m), |
---|
2440 | .clk (clk), .se (se), .so(), .si()); |
---|
2441 | |
---|
2442 | assign intr_vld_qual_m = intr_vld_m & ~kill_thread_m & ~mark4rb_m; |
---|
2443 | |
---|
2444 | dff_s #(1) intr_vldw_ff(.din (intr_vld_qual_m), |
---|
2445 | .q (intr_vld_w), |
---|
2446 | .clk (clk), .se (se), .so(), .si()); |
---|
2447 | |
---|
2448 | // Reset and Idle are prioritized in M. All others in E |
---|
2449 | // reset interrupt |
---|
2450 | assign rstint_m = (rstint_i3[0] & thr_m[0] | |
---|
2451 | rstint_i3[1] & thr_m[1] | |
---|
2452 | rstint_i3[2] & thr_m[2] | |
---|
2453 | rstint_i3[3] & thr_m[3]); |
---|
2454 | |
---|
2455 | assign ifu_tlu_rstint_m = rstint_m & intr_vld_m & ~kill_local_m & |
---|
2456 | ~kill_curr_m; |
---|
2457 | // assign rstint_qual_m = rstint_m & ~ely_kill_thread_m & intr_vld_m; |
---|
2458 | dff_s #(1) rstw_ff(.din (rstint_m), |
---|
2459 | .q (rst_thr_w), |
---|
2460 | .clk (clk), .se(se), .si(), .so()); |
---|
2461 | assign fcl_dtu_rst_thr_w = rst_thr_w & intr_vld_w; |
---|
2462 | |
---|
2463 | // resume interrupt |
---|
2464 | assign resumint_m = (resumint_i3[0] & thr_m[0] | |
---|
2465 | resumint_i3[1] & thr_m[1] | |
---|
2466 | resumint_i3[2] & thr_m[2] | |
---|
2467 | resumint_i3[3] & thr_m[3]); |
---|
2468 | assign resumint_qual_m = resumint_m & ~rstint_m; |
---|
2469 | |
---|
2470 | dff_s #(1) resumw_ff(.din (resumint_qual_m), |
---|
2471 | .q (resum_thr_w), |
---|
2472 | .clk (clk), .se(se), .si(), .so()); |
---|
2473 | assign fcl_dtu_resum_thr_w = resum_thr_w & intr_vld_w; |
---|
2474 | |
---|
2475 | // idle interrupt |
---|
2476 | assign nuke_thr_m = (nuke_thr_i3[0] & thr_m[0] | |
---|
2477 | nuke_thr_i3[1] & thr_m[1] | |
---|
2478 | nuke_thr_i3[2] & thr_m[2] | |
---|
2479 | nuke_thr_i3[3] & thr_m[3]); |
---|
2480 | |
---|
2481 | assign nuke_thr_qual_m = nuke_thr_m & ~rstint_m & ~resumint_m; |
---|
2482 | |
---|
2483 | dff_s #(1) nukw_ff(.din (nuke_thr_qual_m), |
---|
2484 | .q (nuke_thr_w), |
---|
2485 | .clk (clk), |
---|
2486 | .se (se), .si(), .so()); |
---|
2487 | assign fcl_dtu_nuke_thr_w = nuke_thr_w & intr_vld_w; |
---|
2488 | |
---|
2489 | // uncorrected ecc |
---|
2490 | assign ueint_e = (ueint_i3[0] & thr_e[0] & hypv_int_en_d1[0] | |
---|
2491 | ueint_i3[1] & thr_e[1] & hypv_int_en_d1[1] | |
---|
2492 | ueint_i3[2] & thr_e[2] & hypv_int_en_d1[2] | |
---|
2493 | ueint_i3[3] & thr_e[3] & hypv_int_en_d1[3]); |
---|
2494 | assign ueint_qual_e = ueint_e & intr_vld_e; |
---|
2495 | |
---|
2496 | dff_s #(1) uem_ff (.din (ueint_qual_e), |
---|
2497 | .q (ueint_m), |
---|
2498 | .clk (clk), .se (se), .si(), .so()); |
---|
2499 | |
---|
2500 | // assign ueint_m = (ueint_i3[0] & thr_m[0] | |
---|
2501 | // ueint_i3[1] & thr_m[1] | |
---|
2502 | // ueint_i3[2] & thr_m[2] | |
---|
2503 | // ueint_i3[3] & thr_m[3]); |
---|
2504 | |
---|
2505 | assign ueint_trap_m = ueint_m & intr_vld_m & |
---|
2506 | ~(rstint_m | resumint_m | nuke_thr_m); |
---|
2507 | |
---|
2508 | // assign ueint_qual_m = ueint_trap_m & ~ely_kill_thread_m; |
---|
2509 | dff_s #(1) ueintw_ff(.din (ueint_trap_m), |
---|
2510 | .q (ueint_trap_w), |
---|
2511 | .clk (clk), .se(se), .si(), .so()); |
---|
2512 | assign ueint_qual_w = ueint_trap_w & intr_vld_w; |
---|
2513 | |
---|
2514 | // hstk match interrupt |
---|
2515 | assign hintp_e = (hintp_i3[0] & thr_e[0] & hypv_int_en_d1[0] | |
---|
2516 | hintp_i3[1] & thr_e[1] & hypv_int_en_d1[1] | |
---|
2517 | hintp_i3[2] & thr_e[2] & hypv_int_en_d1[2] | |
---|
2518 | hintp_i3[3] & thr_e[3] & hypv_int_en_d1[3]); |
---|
2519 | assign hintp_qual_e = hintp_e & intr_vld_e & ~ueint_e; |
---|
2520 | |
---|
2521 | dff_s #(1) hintpm_ff (.din (hintp_qual_e), |
---|
2522 | .q (hintp_m), |
---|
2523 | .clk (clk), .se (se), .si(), .so()); |
---|
2524 | |
---|
2525 | // assign ifu_tlu_hintp_m = hintp_m & ~kill_local_m & intr_vld_m & |
---|
2526 | // ~(rstint_m | nuke_thr_m | ueint_m); |
---|
2527 | |
---|
2528 | // hw int |
---|
2529 | assign hwint_e = (hwint_i4[0] & thr_e[0] & hypv_int_en_d1[0] | |
---|
2530 | hwint_i4[1] & thr_e[1] & hypv_int_en_d1[1] | |
---|
2531 | hwint_i4[2] & thr_e[2] & hypv_int_en_d1[2] | |
---|
2532 | hwint_i4[3] & thr_e[3] & hypv_int_en_d1[3]); |
---|
2533 | dff_s #(1) hwe_ff(.din (hwint_e), |
---|
2534 | .q (hwint_m), |
---|
2535 | .clk (clk), .se(se), .si(), .so()); |
---|
2536 | |
---|
2537 | assign ifu_tlu_hwint_m = hwint_m & intr_vld_m & ~kill_local_m & |
---|
2538 | ~kill_curr_m & |
---|
2539 | ~(rstint_m | resumint_m | nuke_thr_m | ueint_m | hintp_m); |
---|
2540 | |
---|
2541 | |
---|
2542 | // spu interrupt |
---|
2543 | assign spuint1_e = (spuint1_i3[0] & thr_e[0] & hypv_int_en_d1[0] | |
---|
2544 | spuint1_i3[1] & thr_e[1] & hypv_int_en_d1[1] | |
---|
2545 | spuint1_i3[2] & thr_e[2] & hypv_int_en_d1[2] | |
---|
2546 | spuint1_i3[3] & thr_e[3] & hypv_int_en_d1[3]); |
---|
2547 | assign spuint1_qual_e = spuint1_e & intr_vld_e & ~ueint_e & ~hintp_e; |
---|
2548 | |
---|
2549 | // assign spuint1_m = (spuint1_i3[0] & thr_m[0] | |
---|
2550 | // spuint1_i3[1] & thr_m[1] | |
---|
2551 | // spuint1_i3[2] & thr_m[2] | |
---|
2552 | // spuint1_i3[3] & thr_m[3]); |
---|
2553 | |
---|
2554 | dff_s #(1) spu1m_ff(.din (spuint1_qual_e), |
---|
2555 | .q (spuint1_m), |
---|
2556 | .clk (clk), .se(se), .si(), .so()); |
---|
2557 | |
---|
2558 | assign spuint1_trap_m = spuint1_m & intr_vld_m & |
---|
2559 | ~(rstint_m | resumint_m | nuke_thr_m | hwint_m); |
---|
2560 | |
---|
2561 | // assign spuint1_qual_m = spuint1_trap_m & ~ely_kill_thread_m; |
---|
2562 | |
---|
2563 | dff_s #(1) spiw1_ff(.din (spuint1_trap_m), |
---|
2564 | .q (spuint1_trap_w), |
---|
2565 | .clk (clk), .se(se), .si(), .so()); |
---|
2566 | assign spuint1_w = spuint1_trap_w & intr_vld_w; |
---|
2567 | |
---|
2568 | assign spuint0_e = (spuint0_i3[0] & thr_e[0] & hypv_int_en_d1[0] | |
---|
2569 | spuint0_i3[1] & thr_e[1] & hypv_int_en_d1[1] | |
---|
2570 | spuint0_i3[2] & thr_e[2] & hypv_int_en_d1[2] | |
---|
2571 | spuint0_i3[3] & thr_e[3] & hypv_int_en_d1[3]); |
---|
2572 | |
---|
2573 | assign spuint0_qual_e = spuint0_e & intr_vld_e & ~ueint_e & |
---|
2574 | ~spuint1_e & ~hintp_e; |
---|
2575 | |
---|
2576 | // assign spuint0_m = (spuint0_i3[0] & thr_m[0] | |
---|
2577 | // spuint0_i3[1] & thr_m[1] | |
---|
2578 | // spuint0_i3[2] & thr_m[2] | |
---|
2579 | // spuint0_i3[3] & thr_m[3]); |
---|
2580 | dff_s #(1) spu0m_ff(.din (spuint0_qual_e), |
---|
2581 | .q (spuint0_m), |
---|
2582 | .clk (clk), .se(se), .si(), .so()); |
---|
2583 | |
---|
2584 | assign spuint0_trap_m = spuint0_m & intr_vld_m & |
---|
2585 | ~(rstint_m | nuke_thr_m | resumint_m | |
---|
2586 | hwint_m); |
---|
2587 | |
---|
2588 | // assign spuint0_qual_m = spuint0_trap_m & ~kill_thread_m; |
---|
2589 | |
---|
2590 | dff_s #(1) spiw0_ff(.din (spuint0_trap_m), |
---|
2591 | .q (spuint0_trap_w), |
---|
2592 | .clk (clk), .se(se), .si(), .so()); |
---|
2593 | assign spuint0_w = spuint0_trap_w & intr_vld_w; |
---|
2594 | |
---|
2595 | // assign ifu_spu_trap_ack = {spuint1_w, spuint0_w}; |
---|
2596 | assign ifu_spu_trap_ack = spuint1_w; |
---|
2597 | |
---|
2598 | |
---|
2599 | // software interrupts |
---|
2600 | assign sftint_e = (sftint_i3[0] & thr_e[0] & supv_int_en_d1[0] | |
---|
2601 | sftint_i3[1] & thr_e[1] & supv_int_en_d1[1] | |
---|
2602 | sftint_i3[2] & thr_e[2] & supv_int_en_d1[2] | |
---|
2603 | sftint_i3[3] & thr_e[3] & supv_int_en_d1[3]); |
---|
2604 | |
---|
2605 | assign sftint_qual_e = sftint_e & ~spuint0_e & intr_vld_e & |
---|
2606 | ~ueint_e & ~spuint1_e & ~hintp_e; |
---|
2607 | |
---|
2608 | dff_s #(1) swm_ff(.din (sftint_qual_e), |
---|
2609 | .q (sftint_m), |
---|
2610 | .clk (clk), .se(se), .si(), .so()); |
---|
2611 | |
---|
2612 | // if nothing else, signal sftint! |
---|
2613 | // assign ifu_tlu_sftint_m = (sftint_m & |
---|
2614 | // ~(rstint_m | nuke_thr_m | hintp_m | resumint_m | |
---|
2615 | // hwint_m | spuint1_m | spuint0_m | ueint_m) | |
---|
2616 | // ~(ceint_m | rerr_m)) & |
---|
2617 | // ~kill_local_m & intr_vld_m; |
---|
2618 | |
---|
2619 | assign ifu_tlu_sftint_m = (sftint_m & |
---|
2620 | ~(rstint_m | nuke_thr_m | hintp_m | resumint_m | |
---|
2621 | hwint_m | spuint1_m | spuint0_m | ueint_m)) & |
---|
2622 | ~kill_local_m & ~kill_curr_m & intr_vld_m; |
---|
2623 | |
---|
2624 | |
---|
2625 | // corrected ecc interrupt |
---|
2626 | assign ceint_e = (ceint_i3[0] & thr_e[0] & hypv_int_en_d1[0] | |
---|
2627 | ceint_i3[1] & thr_e[1] & hypv_int_en_d1[1] | |
---|
2628 | ceint_i3[2] & thr_e[2] & hypv_int_en_d1[2] | |
---|
2629 | ceint_i3[3] & thr_e[3] & hypv_int_en_d1[3]); |
---|
2630 | assign ceint_qual_e = ceint_e & intr_vld_e & ~ueint_e & |
---|
2631 | ~spuint1_e & ~spuint0_e & ~hintp_e; |
---|
2632 | |
---|
2633 | // assign ceint_m = (ceint_i3[0] & thr_m[0] | |
---|
2634 | // ceint_i3[1] & thr_m[1] | |
---|
2635 | // ceint_i3[2] & thr_m[2] | |
---|
2636 | // ceint_i3[3] & thr_m[3]); |
---|
2637 | dff_s #(1) cem_ff(.din (ceint_qual_e), |
---|
2638 | .q (ceint_m), |
---|
2639 | .clk (clk), .se(se), .si(), .so()); |
---|
2640 | |
---|
2641 | assign ceint_trap_m = ceint_m & intr_vld_m & |
---|
2642 | ~(rstint_m | nuke_thr_m | resumint_m | |
---|
2643 | sftint_m | hwint_m); |
---|
2644 | |
---|
2645 | // assign ceint_qual_m = ceint_trap_m & ~ely_kill_thread_m; |
---|
2646 | dff_s #(1) ceintw_ff(.din (ceint_trap_m), |
---|
2647 | .q (ceint_trap_w), |
---|
2648 | .clk (clk), .se(se), .si(), .so()); |
---|
2649 | assign ceint_qual_w = ceint_trap_w & intr_vld_w; |
---|
2650 | |
---|
2651 | // resumable error interrupt |
---|
2652 | assign rerr_e = (rerr_i3[0] & thr_e[0] & supv_int_en_d1[0] | |
---|
2653 | rerr_i3[1] & thr_e[1] & supv_int_en_d1[1] | |
---|
2654 | rerr_i3[2] & thr_e[2] & supv_int_en_d1[2] | |
---|
2655 | rerr_i3[3] & thr_e[3] & supv_int_en_d1[3]); |
---|
2656 | assign rerr_qual_e = rerr_e & intr_vld_e & ~ueint_e & ~ceint_e & |
---|
2657 | ~spuint1_e & ~spuint0_e & ~hintp_e; |
---|
2658 | |
---|
2659 | dff_s #(1) rem_ff(.din (rerr_qual_e), |
---|
2660 | .q (rerr_m), |
---|
2661 | .clk (clk), .se(se), .si(), .so()); |
---|
2662 | |
---|
2663 | // assign rerr_m = (rerr_i3[0] & thr_m[0] | |
---|
2664 | // rerr_i3[1] & thr_m[1] | |
---|
2665 | // rerr_i3[2] & thr_m[2] | |
---|
2666 | // rerr_i3[3] & thr_m[3]); |
---|
2667 | |
---|
2668 | // assign ifu_tlu_rerr_m = rerr_m & ~kill_local_m & intr_vld_m & |
---|
2669 | // ~(rstint_m | nuke_thr_m | ueint_m | ceint_m); |
---|
2670 | |
---|
2671 | assign disr_trap_m = (ueint_m | hintp_m | spuint0_m | spuint1_m | |
---|
2672 | ceint_m | rerr_m) & ~rstint_m & ~nuke_thr_m & |
---|
2673 | ~resumint_m & intr_vld_m; |
---|
2674 | |
---|
2675 | // check if a scheduled interrupt evaporated... |
---|
2676 | assign any_intr_m = (ueint_m | ceint_m | spuint0_m | spuint1_m | |
---|
2677 | hintp_m | rerr_m | sftint_m | hwint_m | |
---|
2678 | rstint_m | nuke_thr_m | resumint_m); |
---|
2679 | |
---|
2680 | // ..and rollback if that is the case |
---|
2681 | assign rb_intr_m = ~any_intr_m & intr_vld_m; |
---|
2682 | dff_s #(1) rbint_ff(.din (rb_intr_m), |
---|
2683 | .q (rb_intr_w), |
---|
2684 | .clk (clk), .se(se), .si(), .so()); |
---|
2685 | |
---|
2686 | // use synchronous interrupt signal to switch out thread in swl |
---|
2687 | // assign fcl_dtu_sync_intr_d = (intr_vld_d | immu_miss_crit_d) & ~rb_stg_d; |
---|
2688 | assign fcl_dtu_sync_intr_d = (intr_vld_d) & ~rb_stg_d_crit; |
---|
2689 | |
---|
2690 | // kill the next three interrupts. After that you are on your own. |
---|
2691 | // assign kill_intr_m = ((thr_m & thr_w) == 4'b0) ? |
---|
2692 | // 1'b0 : (intr_vld_w); |
---|
2693 | assign kill_intr_e = ((thr_e & thr_w) == 4'b0) ? |
---|
2694 | 1'b0 : (intr_vld_w); |
---|
2695 | assign kill_intr_d = ((thr_d & thr_w) == 4'b0) ? |
---|
2696 | 1'b0 : (intr_vld_w); |
---|
2697 | assign kill_intr_f = ((thr_f & thr_w) == 4'b0) ? |
---|
2698 | 1'b0 : (intr_vld_w); |
---|
2699 | |
---|
2700 | //-------------------------------- |
---|
2701 | // check if we are in a delay slot |
---|
2702 | //-------------------------------- |
---|
2703 | // remember if the current instruction is a delay slot |
---|
2704 | assign delay_slot_vec_nxt = ({4{dtu_fcl_br_inst_d & inst_vld_d & |
---|
2705 | ~rb_stg_d}} & thr_d | // set |
---|
2706 | delay_slot_vec & |
---|
2707 | ~(thr_d & {4{inst_vld_d & |
---|
2708 | ~rb_stg_d & |
---|
2709 | ~intr_vld_d}})) & |
---|
2710 | ~(trap_thr & {4{trappc_vld_w2}}); |
---|
2711 | // & ~late_flush_w2; |
---|
2712 | // Need to be a little pessimitic: can't clear the delay slot vec |
---|
2713 | // after a utrap, since we may still be in the delay slot when we |
---|
2714 | // re-execute |
---|
2715 | |
---|
2716 | dffr_s #(4) ds_reg(.din (delay_slot_vec_nxt), |
---|
2717 | .q (delay_slot_vec), |
---|
2718 | .rst (fcl_reset), |
---|
2719 | .clk (clk), .se(se), .si(), .so()); |
---|
2720 | assign fcl_dec_dslot_s = (delay_slot_vec[0] & thr_f[0] | |
---|
2721 | delay_slot_vec[1] & thr_f[1] | |
---|
2722 | delay_slot_vec[2] & thr_f[2] | |
---|
2723 | delay_slot_vec[3] & thr_f[3]); |
---|
2724 | |
---|
2725 | |
---|
2726 | //------------------------------ |
---|
2727 | // NIR control |
---|
2728 | //------------------------------ |
---|
2729 | // use nir if va[2] of previous fetch is a zero (i.e lower word) |
---|
2730 | dff_s #(1) va2_ff(.din (fdp_fcl_va2_bf), |
---|
2731 | .clk (clk), |
---|
2732 | .q (va2_f), |
---|
2733 | .se (se), .si(), .so()); |
---|
2734 | |
---|
2735 | assign usep_bf = rdreq_f & ~va2_f & ~ntpc_thisthr & ~stall_f; |
---|
2736 | assign set_usen_bf = usep_bf & ~ely_stall_thisthr_f & dtu_fcl_running_s; |
---|
2737 | |
---|
2738 | // need to kill usen if trap or interrupt or flush |
---|
2739 | assign thr_usen_nxt = ({4{set_usen_bf}} & thr_f | // set usen |
---|
2740 | thr_usen_bf & ~val_thr_f) & // keep old value |
---|
2741 | ~((thr_d & {4{dtu_fcl_br_inst_d}}) | |
---|
2742 | (thr_s1 & {4{ic_miss_s1}}) | |
---|
2743 | (thr_e & {4{erb_dtu_ifeterr_d1 & inst_vld_d1}}) | |
---|
2744 | (clear_s_d1) | |
---|
2745 | (ntpc_vld) | |
---|
2746 | (rb_w2 | rb_froms)); // reset usen (wins) |
---|
2747 | // & ~dtu_fcl_flush_nir |
---|
2748 | |
---|
2749 | dffr_s #(4) thr_usen_reg(.din (thr_usen_nxt), |
---|
2750 | .clk (clk), |
---|
2751 | .q (thr_usen_bf), |
---|
2752 | .rst (fcl_reset), |
---|
2753 | .se (se), .si(), .so()); |
---|
2754 | |
---|
2755 | /* |
---|
2756 | // Use hand instantiated mux |
---|
2757 | bw_u1_ao2222_4x UZsize_usn_mx(.z (usen_iso_bf) |
---|
2758 | .a2 (thr_usen_bf[0]), |
---|
2759 | .b2 (thr_usen_bf[1]), |
---|
2760 | .c2 (thr_usen_bf[2]), |
---|
2761 | .d2 (thr_usen_bf[3]), |
---|
2762 | .a1 (nextthr_bf_buf[0]), |
---|
2763 | .b1 (nextthr_bf_buf[1]), |
---|
2764 | .c1 (nextthr_bf_buf[2]), |
---|
2765 | .d1 (nextthr_bf_buf[3])); |
---|
2766 | |
---|
2767 | // isolate from critical path |
---|
2768 | bw_u1_buf_5x UZsize_usn_iso(.z(usen_bf), .a(usen_iso_bf)); |
---|
2769 | */ |
---|
2770 | |
---|
2771 | assign usen_iso_bf = (thr_usen_bf[0] & nextthr_bf_buf[0] | |
---|
2772 | thr_usen_bf[1] & nextthr_bf_buf[1] | |
---|
2773 | thr_usen_bf[2] & nextthr_bf_buf[2] | |
---|
2774 | thr_usen_bf[3] & nextthr_bf_buf[3]); |
---|
2775 | assign usen_bf = usen_iso_bf; |
---|
2776 | |
---|
2777 | |
---|
2778 | |
---|
2779 | //------------------------------ |
---|
2780 | // Switch Control |
---|
2781 | //------------------------------ |
---|
2782 | // Switch IF |
---|
2783 | // 1. Another thread is ready OR |
---|
2784 | // 2. We hit a switch condition or Imiss and another thread is |
---|
2785 | // speculatively ready |
---|
2786 | // 3. No thread is running and another thread is speculatively ready |
---|
2787 | // 4. The DTU calls for a thread switch and another thread is ready |
---|
2788 | // (NOTE: if we hit a switch condition or Imiss and no thread is |
---|
2789 | // speculatively or otherwise ready we stall the pipe). |
---|
2790 | // |
---|
2791 | // New plan: switch if another thread is ready or spec ready. |
---|
2792 | // |
---|
2793 | |
---|
2794 | // assign switch_bf = dtu_fcl_ntr_s; |
---|
2795 | bw_u1_buf_20x UZsize_swbuf(.a (dtu_fcl_ntr_s), |
---|
2796 | .z (switch_bf)); |
---|
2797 | |
---|
2798 | // assign switch_bf = dtu_fcl_ntr_s & ~imsto_nextthr_s1; |
---|
2799 | // assign switch_bf = dtu_fcl_ntr_s & ~(imsto_nextthr_s1 | kill_nextthr_w | |
---|
2800 | // intrto_nextthr_d); |
---|
2801 | |
---|
2802 | // assign fcl_dtu_switch_s = switch_bf & ~all_stallreq & ~rst_stallreq; |
---|
2803 | // assign fcl_dtu_switch_s = switch_bf & ~kill_nextthr_w; |
---|
2804 | |
---|
2805 | // TBD: No need to send this anymore, since switch_bf = ntr_s |
---|
2806 | // assign fcl_dtu_switch_s = switch_bf; // sw out curr and sw in next |
---|
2807 | |
---|
2808 | assign fcl_swl_swout_f = stall_f; // sw out curr but don't sw in next |
---|
2809 | // Note: need fcl_swl_swout_f and dtu_fcl_running_s to sync swl and |
---|
2810 | // fcl at all times. |
---|
2811 | |
---|
2812 | assign switch_qual_bf = switch_bf & ~rst_stallreq; |
---|
2813 | dff_s #(1) sw_ff (.din (switch_qual_bf), |
---|
2814 | .clk (clk), |
---|
2815 | .q (switch_s2), |
---|
2816 | .se (se), .si(), .so()); |
---|
2817 | |
---|
2818 | dff_s #(1) tmfn_ff (.din (switch_bf), |
---|
2819 | .clk (clk), |
---|
2820 | .q (tm_fd_l), |
---|
2821 | .se (se), .si(), .so()); |
---|
2822 | |
---|
2823 | // need to qual with immu_fault to avoid X's |
---|
2824 | // assign fcl_dtu_swc_s = fdp_fcl_swc_s2 & inst_vld_s_crit & |
---|
2825 | // ~immu_fault_f & ~part_stall_thisthr_f; |
---|
2826 | // assign fcl_dtu_swc_s = fdp_fcl_swc_s2 & inst_vld_s_crit & |
---|
2827 | // ~immu_fault_f & ~imsto_thisthr_s1 & ~rb_stg_s; |
---|
2828 | assign fcl_swl_swcvld_s = inst_vld_s_crit & ~immu_fault_f & |
---|
2829 | ~imsto_thisthr_s1 & ~rb_stg_s; |
---|
2830 | |
---|
2831 | |
---|
2832 | //------------------------------ |
---|
2833 | // Thread pipe |
---|
2834 | //------------------------------ |
---|
2835 | |
---|
2836 | //`ifdef VERPLEX |
---|
2837 | // $constraint nthr_1h4 ($one_hot(dtu_fcl_nextthr_bf[3:0])); |
---|
2838 | // $constraint thrf_1h4 ($one_hot(thr_f[3:0])); |
---|
2839 | //`endif |
---|
2840 | |
---|
2841 | // Keep track the thread in each pipe stage |
---|
2842 | assign rstt = (~fcl_reset & (rst_stallreq_d1 & ~arst_vld_f)) | rst_tri_en; |
---|
2843 | assign swt = (~rst_stallreq_d1 & ~arst_vld_f & switch_bf | fcl_reset) & |
---|
2844 | ~rst_tri_en; |
---|
2845 | assign samet = (~rst_stallreq_d1 & ~switch_bf | arst_vld_f) & |
---|
2846 | ~fcl_reset & ~rst_tri_en; |
---|
2847 | |
---|
2848 | mux3ds #(4) nxttthr_mux(.dout (thr_bf[3:0]), |
---|
2849 | .in0 (thr_f[3:0]), |
---|
2850 | .in1 (nextthr_bf_buf[3:0]), |
---|
2851 | .in2 (rstint_penc[3:0]), |
---|
2852 | .sel0 (samet), |
---|
2853 | .sel1 (swt), |
---|
2854 | .sel2 (rstt)); |
---|
2855 | |
---|
2856 | assign thr_match_nw = (thr_w[0] & nextthr_bf_buf[0] | |
---|
2857 | thr_w[1] & nextthr_bf_buf[1] | |
---|
2858 | thr_w[2] & nextthr_bf_buf[2] | |
---|
2859 | thr_w[3] & nextthr_bf_buf[3]); |
---|
2860 | |
---|
2861 | assign thr_match_nd = (thr_d[0] & nextthr_bf_buf[0] | |
---|
2862 | thr_d[1] & nextthr_bf_buf[1] | |
---|
2863 | thr_d[2] & nextthr_bf_buf[2] | |
---|
2864 | thr_d[3] & nextthr_bf_buf[3]); |
---|
2865 | |
---|
2866 | // assign thr_match_ne = (thr_e[0] & dtu_fcl_nextthr_bf[0] | |
---|
2867 | // thr_e[1] & dtu_fcl_nextthr_bf[1] | |
---|
2868 | // thr_e[2] & dtu_fcl_nextthr_bf[2] | |
---|
2869 | // thr_e[3] & dtu_fcl_nextthr_bf[3]); |
---|
2870 | // qualify inst_vld_e in fcl itself |
---|
2871 | |
---|
2872 | // bw_u1_ao2222_4x UZsize_tmne(.z (thr_match_ne), |
---|
2873 | // .a1 (val_thr_e[0]), |
---|
2874 | // .b1 (val_thr_e[1]), |
---|
2875 | // .c1 (val_thr_e[2]), |
---|
2876 | // .d1 (val_thr_e[3]), |
---|
2877 | // .a2 (dtu_fcl_nextthr_bf[0]), |
---|
2878 | // .b2 (dtu_fcl_nextthr_bf[1]), |
---|
2879 | // .c2 (dtu_fcl_nextthr_bf[2]), |
---|
2880 | // .d2 (dtu_fcl_nextthr_bf[3])); |
---|
2881 | |
---|
2882 | wire tmne_10, |
---|
2883 | tmne_32; |
---|
2884 | bw_u1_aoi22_2x UZsize_tmne10(.z (tmne_10), |
---|
2885 | .a1 (dtu_fcl_nextthr_bf[0]), |
---|
2886 | .b1 (dtu_fcl_nextthr_bf[1]), |
---|
2887 | .a2 (val_thr_e[0]), |
---|
2888 | .b2 (val_thr_e[1])); |
---|
2889 | bw_u1_aoi22_2x UZsize_tmne32(.z (tmne_32), |
---|
2890 | .a1 (dtu_fcl_nextthr_bf[2]), |
---|
2891 | .b1 (dtu_fcl_nextthr_bf[3]), |
---|
2892 | .a2 (val_thr_e[2]), |
---|
2893 | .b2 (val_thr_e[3])); |
---|
2894 | bw_u1_nand2_4x UZsize_tmne30(.z (thr_match_ne), |
---|
2895 | .a (tmne_10), |
---|
2896 | .b (tmne_32)); |
---|
2897 | |
---|
2898 | |
---|
2899 | dff_s #(4) thrf_reg(.din (thr_bf), // thr_f may be 4'b0000 but it has |
---|
2900 | .clk (clk), // to reset to 4'b0001 |
---|
2901 | .q (thr_f_flop), |
---|
2902 | .se (se), .si(), .so()); |
---|
2903 | |
---|
2904 | bw_u1_buf_10x UZsize_tfcrit0(.a (thr_f_flop[0]), .z(thr_f_crit[0])); |
---|
2905 | bw_u1_buf_10x UZsize_tfcrit1(.a (thr_f_flop[1]), .z(thr_f_crit[1])); |
---|
2906 | bw_u1_buf_10x UZsize_tfcrit2(.a (thr_f_flop[2]), .z(thr_f_crit[2])); |
---|
2907 | bw_u1_buf_10x UZsize_tfcrit3(.a (thr_f_flop[3]), .z(thr_f_crit[3])); |
---|
2908 | |
---|
2909 | bw_u1_buf_10x UZsize_tfncr0(.a (thr_f_flop[0]), .z(thr_f[0])); |
---|
2910 | bw_u1_buf_10x UZsize_tfncr1(.a (thr_f_flop[1]), .z(thr_f[1])); |
---|
2911 | bw_u1_buf_10x UZsize_tfncr2(.a (thr_f_flop[2]), .z(thr_f[2])); |
---|
2912 | bw_u1_buf_10x UZsize_tfncr3(.a (thr_f_flop[3]), .z(thr_f[3])); |
---|
2913 | |
---|
2914 | assign ifu_exu_tid_s2[1] = thr_f[3] | thr_f[2]; |
---|
2915 | assign ifu_exu_tid_s2[0] = thr_f[3] | thr_f[1]; |
---|
2916 | assign ifu_lsu_thrid_s = ifu_exu_tid_s2; |
---|
2917 | assign fcl_dtu_thr_f = thr_f; |
---|
2918 | |
---|
2919 | // assign thr_s1_next = inst_vld_f ? thr_f : thr_s1; |
---|
2920 | assign thr_s1_next[0] = thr_f[0]; |
---|
2921 | assign thr_s1_next[1] = ~thr_f[0] & thr_f[1]; |
---|
2922 | assign thr_s1_next[2] = ~thr_f[0] & ~thr_f[1] & thr_f[2]; |
---|
2923 | assign thr_s1_next[3] = ~thr_f[0] & ~thr_f[1] & ~thr_f[2]; |
---|
2924 | |
---|
2925 | //`ifdef VERPLEX |
---|
2926 | // $constraint thr_s1_1h4 ($one_hot(thr_s1_next[3:0])); |
---|
2927 | //`endif |
---|
2928 | |
---|
2929 | dff_s #(4) thrs1_reg(.din (thr_s1_next), |
---|
2930 | .clk (clk), |
---|
2931 | .q (thr_s1), |
---|
2932 | .se (se), .si(), .so()); |
---|
2933 | |
---|
2934 | dff_s #(4) thrd_reg(.din (thr_s1_next), |
---|
2935 | .clk (clk), |
---|
2936 | .q (thr_d), |
---|
2937 | .se (se), .si(), .so()); |
---|
2938 | |
---|
2939 | assign fcl_ifq_thr_s1[0] = thr_s1[3] | thr_s1[1]; |
---|
2940 | assign fcl_ifq_thr_s1[1] = thr_s1[3] | thr_s1[2]; |
---|
2941 | |
---|
2942 | assign ifu_tlu_thrid_d[1] = thr_d[3] | thr_d[2]; |
---|
2943 | assign ifu_tlu_thrid_d[0] = thr_d[3] | thr_d[1]; |
---|
2944 | |
---|
2945 | assign thr_match_fs1 = (thr_d[0] & thr_f_crit[0] | |
---|
2946 | thr_d[1] & thr_f_crit[1] | |
---|
2947 | thr_d[2] & thr_f_crit[2] | |
---|
2948 | thr_d[3] & thr_f_crit[3]); |
---|
2949 | assign thr_match_fd = thr_match_fs1; |
---|
2950 | assign thr_match_fe = (thr_e[0] & thr_f[0] | |
---|
2951 | thr_e[1] & thr_f[1] | |
---|
2952 | thr_e[2] & thr_f[2] | |
---|
2953 | thr_e[3] & thr_f[3]); |
---|
2954 | assign thr_match_fm = (thr_m[0] & thr_f[0] | |
---|
2955 | thr_m[1] & thr_f[1] | |
---|
2956 | thr_m[2] & thr_f[2] | |
---|
2957 | thr_m[3] & thr_f[3]); |
---|
2958 | // assign thr_match_ft = (trap_thr[0] & thr_f[0] | |
---|
2959 | // trap_thr[1] & thr_f[1] | |
---|
2960 | // trap_thr[2] & thr_f[2] | |
---|
2961 | // trap_thr[3] & thr_f[3]); |
---|
2962 | |
---|
2963 | dffr_s #(4) thre_reg(.din (thr_d), |
---|
2964 | .clk (clk), |
---|
2965 | .rst (fcl_reset), |
---|
2966 | .q (thr_e), |
---|
2967 | .se (se), .si(), .so()); |
---|
2968 | |
---|
2969 | dffr_s #(4) thre2_reg(.din (thr_d), |
---|
2970 | .clk (clk), |
---|
2971 | .rst (fcl_reset), |
---|
2972 | .q (thr_e_v2), |
---|
2973 | .se (se), .si(), .so()); |
---|
2974 | |
---|
2975 | assign ifu_tlu_thrid_e[1] = thr_e[3] | thr_e[2]; |
---|
2976 | assign ifu_tlu_thrid_e[0] = thr_e[3] | thr_e[1]; |
---|
2977 | |
---|
2978 | assign thr_match_de = (thr_d[0] & thr_e[0] | |
---|
2979 | thr_d[1] & thr_e[1] | |
---|
2980 | thr_d[2] & thr_e[2] | |
---|
2981 | thr_d[3] & thr_e[3]); |
---|
2982 | |
---|
2983 | assign thr_match_dm = (thr_d[0] & thr_m[0] | |
---|
2984 | thr_d[1] & thr_m[1] | |
---|
2985 | thr_d[2] & thr_m[2] | |
---|
2986 | thr_d[3] & thr_m[3]); |
---|
2987 | |
---|
2988 | dff_s #(4) thrm_reg(.din (thr_e), |
---|
2989 | .clk (clk), |
---|
2990 | .q (thr_m), |
---|
2991 | .se (se), .si(), .so()); |
---|
2992 | |
---|
2993 | dff_s #(4) thrw_reg(.din (thr_m), |
---|
2994 | .clk (clk), |
---|
2995 | .q (thr_w), |
---|
2996 | .se (se), .si(), .so()); |
---|
2997 | |
---|
2998 | assign sas_thrid_w[1] = thr_w[3] | thr_w[2]; |
---|
2999 | assign sas_thrid_w[0] = thr_w[3] | thr_w[1]; |
---|
3000 | |
---|
3001 | assign thr_match_fw = (thr_f[0] & thr_w[0] | |
---|
3002 | thr_f[1] & thr_w[1] | |
---|
3003 | thr_f[2] & thr_w[2] | |
---|
3004 | thr_f[3] & thr_w[3]); |
---|
3005 | |
---|
3006 | assign thr_match_fw2 = (thr_f[0] & thr_w2[0] | |
---|
3007 | thr_f[1] & thr_w2[1] | |
---|
3008 | thr_f[2] & thr_w2[2] | |
---|
3009 | thr_f[3] & thr_w2[3]); |
---|
3010 | |
---|
3011 | assign thr_match_dw = (thr_d[0] & thr_w[0] | |
---|
3012 | thr_d[1] & thr_w[1] | |
---|
3013 | thr_d[2] & thr_w[2] | |
---|
3014 | thr_d[3] & thr_w[3]); |
---|
3015 | |
---|
3016 | assign thr_match_dw2 = (thr_d[0] & thr_w2[0] | |
---|
3017 | thr_d[1] & thr_w2[1] | |
---|
3018 | thr_d[2] & thr_w2[2] | |
---|
3019 | thr_d[3] & thr_w2[3]); |
---|
3020 | |
---|
3021 | assign thr_match_em = (thr_e[0] & thr_m[0] | |
---|
3022 | thr_e[1] & thr_m[1] | |
---|
3023 | thr_e[2] & thr_m[2] | |
---|
3024 | thr_e[3] & thr_m[3]); |
---|
3025 | |
---|
3026 | assign thr_match_ew = (thr_e_v2[0] & thr_w[0] | |
---|
3027 | thr_e_v2[1] & thr_w[1] | |
---|
3028 | thr_e_v2[2] & thr_w[2] | |
---|
3029 | thr_e_v2[3] & thr_w[3]); |
---|
3030 | |
---|
3031 | dff_s #(1) stmw2_ff(.din (thr_match_ew), |
---|
3032 | .q (same_thr_mw2), |
---|
3033 | .clk (clk), .se (se), .si(), .so()); |
---|
3034 | |
---|
3035 | assign thr_match_ew2 = (thr_e[0] & thr_w2[0] | |
---|
3036 | thr_e[1] & thr_w2[1] | |
---|
3037 | thr_e[2] & thr_w2[2] | |
---|
3038 | thr_e[3] & thr_w2[3]); |
---|
3039 | |
---|
3040 | assign thr_match_mw = (thr_m[0] & thr_w[0] | |
---|
3041 | thr_m[1] & thr_w[1] | |
---|
3042 | thr_m[2] & thr_w[2] | |
---|
3043 | thr_m[3] & thr_w[3]); |
---|
3044 | |
---|
3045 | dff_s #(4) thrw2_reg(.din (thr_w), |
---|
3046 | .clk (clk), |
---|
3047 | .q (thr_w2), |
---|
3048 | .se (se), .si(), .so()); |
---|
3049 | |
---|
3050 | |
---|
3051 | //------------------------- |
---|
3052 | // Rollback |
---|
3053 | //------------------------- |
---|
3054 | |
---|
3055 | // 04/05/02 |
---|
3056 | // Looks like we made a mistake with rollback. Should never |
---|
3057 | // rollback to S. In the event of a dmiss or mul contention, just |
---|
3058 | // kill all the instructions and rollback to F. This adds one |
---|
3059 | // cycle to the dmiss penalty and to the mul latency if we have to |
---|
3060 | // wait, both not a very high price to pay. This would have saved |
---|
3061 | // lots of hours of design and verif time. |
---|
3062 | // |
---|
3063 | assign rb2_inst_d = thr_match_dw & inst_vld_d & dtu_fcl_rollback_g; |
---|
3064 | assign rb1_inst_s = thr_match_fw & inst_vld_s & dtu_fcl_rollback_g; |
---|
3065 | assign rb0_inst_bf = thr_match_nw & switch_bf & dtu_fcl_rollback_g; |
---|
3066 | |
---|
3067 | // assign rt1_inst_s = thr_match_fd & inst_vld_s & retract_inst_d; |
---|
3068 | // assign rt0_inst_bf = thr_match_nd & dtu_fcl_ntr_s & retract_inst_d; |
---|
3069 | |
---|
3070 | // assign retract_iferr_d = thr_match_de & erb_dtu_ifeterr_d1 & inst_vld_d1 & |
---|
3071 | // ~kill_curr_e & fcl_dtu_inst_vld_d; |
---|
3072 | assign retract_iferr_d1 = erb_dtu_ifeterr_d1 & inst_vld_d1; |
---|
3073 | |
---|
3074 | assign retract_inst_d = retract_iferr_d1 & thr_match_de & |
---|
3075 | fcl_dtu_inst_vld_d | |
---|
3076 | mark4rb_d | |
---|
3077 | dtu_fcl_retract_d; |
---|
3078 | |
---|
3079 | assign rt1_inst_s = thr_match_fd & inst_vld_s & dtu_fcl_retract_d | |
---|
3080 | mark4rb_s; |
---|
3081 | // | thr_match_fe & inst_vld_s & retract_iferr_d1; |
---|
3082 | |
---|
3083 | // TBD: This is not necessary since the thread will switch out and |
---|
3084 | // stall whatever makes its way to the S stage. |
---|
3085 | // NOTE: rb0_inst *is needed* however. |
---|
3086 | assign rt0_inst_bf = thr_match_nd & switch_bf & dtu_fcl_retract_d; |
---|
3087 | // | thr_match_ne & dtu_fcl_ntr_s & retract_iferr_d1; |
---|
3088 | |
---|
3089 | assign retract_iferr_qual_d1 = retract_iferr_d1 & thr_match_de & |
---|
3090 | fcl_dtu_inst_vld_d & |
---|
3091 | ~(dtu_fcl_rollback_g & thr_match_ew); |
---|
3092 | |
---|
3093 | dff_s rbe_ff(.din (rb2_inst_d), |
---|
3094 | .q (rb2_inst_e), |
---|
3095 | .clk (clk), |
---|
3096 | .se (se), .si(), .so()); |
---|
3097 | |
---|
3098 | dff_s rte_ff(.din (retract_inst_d), |
---|
3099 | .q (rt2_inst_e), |
---|
3100 | .clk (clk), |
---|
3101 | .se (se), .si(), .so()); |
---|
3102 | |
---|
3103 | dff_s rbd_ff(.din (rb1_inst_s), |
---|
3104 | .q (rb1_inst_d), |
---|
3105 | .clk (clk), |
---|
3106 | .se (se), .si(), .so()); |
---|
3107 | |
---|
3108 | dff_s rtd_ff(.din (rt1_inst_s), |
---|
3109 | .q (rt1_inst_d), |
---|
3110 | .clk (clk), |
---|
3111 | .se (se), .si(), .so()); |
---|
3112 | |
---|
3113 | dff_s rbs_ff(.din (rb0_inst_bf), |
---|
3114 | .q (rb0_inst_s), |
---|
3115 | .clk (clk), |
---|
3116 | .se (se), .si(), .so()); |
---|
3117 | |
---|
3118 | // TBD: is this necessary? |
---|
3119 | dff_s rts_ff(.din (rt0_inst_bf), |
---|
3120 | .q (rt0_inst_s), |
---|
3121 | .clk (clk), |
---|
3122 | .se (se), .si(), .so()); |
---|
3123 | |
---|
3124 | dff_s rtiferr_ff(.din (retract_iferr_qual_d1), |
---|
3125 | .q (retract_iferr_e), |
---|
3126 | .clk (clk), |
---|
3127 | .se (se), .si(), .so()); |
---|
3128 | |
---|
3129 | assign rb_stg_s = (rb0_inst_s | rt0_inst_s) & tm_fd_l | |
---|
3130 | (rb1_inst_d | rt1_inst_d) & ~tm_fd_l; |
---|
3131 | assign rb_stg_d_crit = rb1_inst_d | rt1_inst_d; |
---|
3132 | assign rb_stg_e = rb2_inst_e | rt2_inst_e; |
---|
3133 | |
---|
3134 | bw_u1_buf_5x UZsize_rbd_buf(.a (rb_stg_d_crit), |
---|
3135 | .z (rb_stg_d)); |
---|
3136 | |
---|
3137 | // determine rollback amount |
---|
3138 | assign rb_frome = {4{(rb2_inst_e | rt2_inst_e) & |
---|
3139 | (inst_vld_e | intr_vld_e)}} & thr_e; |
---|
3140 | assign rb_fromd = {4{(rb1_inst_d | rt1_inst_d) & |
---|
3141 | (inst_vld_d | intr_vld_d)}} & thr_d; |
---|
3142 | assign rb_froms = {4{rb_stg_s & inst_vld_s_crit}} & thr_f; |
---|
3143 | assign rb_w2 = rb_frome | rb_fromd; |
---|
3144 | assign rb_for_iferr_e = {4{retract_iferr_e}} & thr_e; |
---|
3145 | |
---|
3146 | //------------------------------ |
---|
3147 | // Branch Control |
---|
3148 | //------------------------------ |
---|
3149 | // final portion of branch evaluation |
---|
3150 | wire brtaken_e_l; |
---|
3151 | bw_u1_buf_20x UZsize_bcbf(.z(fcl_dcl_regz_e), |
---|
3152 | .a(exu_ifu_regz_e)); |
---|
3153 | |
---|
3154 | bw_u1_muxi21_6x UZsize_bcmux(.z(brtaken_e_l), |
---|
3155 | .d0(dcl_fcl_bcregz0_e), |
---|
3156 | .d1(dcl_fcl_bcregz1_e), |
---|
3157 | .s(exu_ifu_regz_e)); |
---|
3158 | |
---|
3159 | bw_u1_inv_15x UZsize_bcinv(.z(brtaken_e), |
---|
3160 | .a(brtaken_e_l)); |
---|
3161 | |
---|
3162 | // Branch is taken in the E stage to thr_e. Below we check to see |
---|
3163 | // if this is the same as the next thread we will switch to |
---|
3164 | |
---|
3165 | // isolate non critical section |
---|
3166 | bw_u1_buf_5x UZsize_btbuf(.z (brtaken_unq_e), |
---|
3167 | .a (brtaken_e)); |
---|
3168 | assign brtaken_buf_e = brtaken_unq_e & inst_vld_qual_e & ~kill_curr_e; |
---|
3169 | |
---|
3170 | // assign thr_match_ne_norst = thr_match_ne & ~rst_sw_bf; |
---|
3171 | // assign brto_nxtthr_bf = thr_match_ne & brtaken_e; |
---|
3172 | bw_u1_nand2_4x UZsize_btkn_ntl(.a (brtaken_e), |
---|
3173 | .b (thr_match_ne), |
---|
3174 | .z (brto_nxtthr_bf_l)); |
---|
3175 | |
---|
3176 | // bw_u1_inv_8x UZsize_btkn_bf(.a (brto_nxtthr_bf_l), |
---|
3177 | // .z (brto_nxtthr_bf)); |
---|
3178 | |
---|
3179 | dff_s #(1) br_ff(.din (brtaken_buf_e), |
---|
3180 | .q (brtaken_m), |
---|
3181 | .clk (clk), |
---|
3182 | .se (se), .si(), .so()); |
---|
3183 | |
---|
3184 | |
---|
3185 | //---------------------------------------------------------------------- |
---|
3186 | // PC related control |
---|
3187 | //---------------------------------------------------------------------- |
---|
3188 | |
---|
3189 | // Choose next IC address |
---|
3190 | // IC address is chosen from |
---|
3191 | // 1. Next PC assuming no switch |
---|
3192 | // 2. Branch PC if E stage branch is to next thread |
---|
3193 | // 3. Saved F stage Thread PC if we switch threads |
---|
3194 | |
---|
3195 | assign fcl_icd_index_sel_ifq_bf = allow_ifq_access_icd_bf; |
---|
3196 | assign fcl_ifq_grant_bf = allow_ifq_access_icd_bf; |
---|
3197 | |
---|
3198 | // Select branch PC |
---|
3199 | // assign fcl_fdp_icaddr_sel_br_bf_l = ~(~all_stallreq & |
---|
3200 | // brto_nxtthr_bf & |
---|
3201 | // switch_bf); |
---|
3202 | // |
---|
3203 | // // Select the switch PC from thread PC register |
---|
3204 | // assign fcl_fdp_icaddr_sel_swpc_bf_l = ~(~all_stallreq & |
---|
3205 | // ~usen_bf & |
---|
3206 | // ~brto_nxtthr_bf & |
---|
3207 | // switch_bf); |
---|
3208 | // |
---|
3209 | // // Select current thread's next PC or IC write addr (PC/PC+4/I$ wraddr) |
---|
3210 | // assign fcl_fdp_icaddr_sel_curr_bf_l = ~(~all_stallreq & |
---|
3211 | // ~(stall_f | usep_bf) & |
---|
3212 | // ~switch_bf); |
---|
3213 | // |
---|
3214 | // assign fcl_fdp_icaddr_sel_ifq_bf_l = ~(all_stallreq | |
---|
3215 | // (stall_f | usep_bf) & ~switch_bf | |
---|
3216 | // ~brto_nxtthr_bf & usen_bf & |
---|
3217 | // (switch_bf | stall_f | usep_bf)); |
---|
3218 | |
---|
3219 | |
---|
3220 | |
---|
3221 | // assign sw_or_async_stall = (switch_bf & ~rst_stallreq | rst_sw_bf); |
---|
3222 | wire sw_or_async_stall_l; |
---|
3223 | assign rst_stallreq_l = ~rst_stallreq; |
---|
3224 | bw_u1_aoi21_4x UZsize_swstl_aoi(.z (sw_or_async_stall_l), |
---|
3225 | .a (rst_sw_bf), |
---|
3226 | .b1 (switch_bf), |
---|
3227 | .b2 (rst_stallreq_l)); |
---|
3228 | assign sw_or_async_stall = ~sw_or_async_stall_l; |
---|
3229 | |
---|
3230 | // assign icadr_selbr = sw_or_async_stall & brto_nxtthr_bf; |
---|
3231 | assign sw_match_ne_norst = sw_or_async_stall & thr_match_ne; |
---|
3232 | bw_u1_nand2_10x UZfix_icad_br(.a (brtaken_e), |
---|
3233 | .b (sw_match_ne_norst), |
---|
3234 | .z (icadr_selbr_l)); |
---|
3235 | |
---|
3236 | // assign icadr_selsw = sw_or_async_stall & ~brto_nxtthr_bf; |
---|
3237 | bw_u1_nand2_15x UZfix_icad_sw(.a (brto_nxtthr_bf_l), |
---|
3238 | .b (sw_or_async_stall), |
---|
3239 | .z (icadr_selsw_l)); |
---|
3240 | |
---|
3241 | |
---|
3242 | // select next PC |
---|
3243 | assign fcl_fdp_pcbf_sel_br_bf_l = icadr_selbr_l; |
---|
3244 | assign fcl_fdp_pcbf_sel_swpc_bf_l = icadr_selsw_l ; |
---|
3245 | assign fcl_fdp_pcbf_sel_nosw_bf_l = ~sw_or_async_stall_l; |
---|
3246 | |
---|
3247 | // Select PC to switch to in the event of a switch |
---|
3248 | // No need to protect during scan |
---|
3249 | // NOTE: SWL guarantees nextthr_bf is one hot |
---|
3250 | // assign fcl_fdp_next_thr_bf_l = rst_stallreq_d1 ? ~rstint_penc : |
---|
3251 | // ~dtu_fcl_nextthr_bf; |
---|
3252 | |
---|
3253 | wire [3:0] next_thr_bf_l; |
---|
3254 | wire nt_sel_rst; |
---|
3255 | assign nt_sel_rst = rst_stallreq_d1 | rst_tri_en; |
---|
3256 | |
---|
3257 | bw_u1_muxi21_2x UZfix_nthr_mx0(.z (next_thr_bf_l[0]), |
---|
3258 | .d0 (dtu_fcl_nextthr_bf[0]), |
---|
3259 | .d1 (rstint_penc[0]), |
---|
3260 | .s (nt_sel_rst)); |
---|
3261 | bw_u1_muxi21_2x UZfix_nthr_mx1(.z (next_thr_bf_l[1]), |
---|
3262 | .d0 (dtu_fcl_nextthr_bf[1]), |
---|
3263 | .d1 (rstint_penc[1]), |
---|
3264 | .s (nt_sel_rst)); |
---|
3265 | bw_u1_muxi21_2x UZfix_nthr_mx2(.z (next_thr_bf_l[2]), |
---|
3266 | .d0 (dtu_fcl_nextthr_bf[2]), |
---|
3267 | .d1 (rstint_penc[2]), |
---|
3268 | .s (nt_sel_rst)); |
---|
3269 | bw_u1_muxi21_2x UZfix_nthr_mx3(.z (next_thr_bf_l[3]), |
---|
3270 | .d0 (dtu_fcl_nextthr_bf[3]), |
---|
3271 | .d1 (rstint_penc[3]), |
---|
3272 | .s (nt_sel_rst)); |
---|
3273 | assign fcl_fdp_next_thr_bf_l = next_thr_bf_l; |
---|
3274 | |
---|
3275 | |
---|
3276 | // assign nextthr_bf_buf = dtu_fcl_nextthr_bf; |
---|
3277 | bw_u1_buf_20x UZsize_ntbf0(.a (dtu_fcl_nextthr_bf[0]), |
---|
3278 | .z (nextthr_bf_buf[0])); |
---|
3279 | bw_u1_buf_20x UZsize_ntbf1(.a (dtu_fcl_nextthr_bf[1]), |
---|
3280 | .z (nextthr_bf_buf[1])); |
---|
3281 | bw_u1_buf_20x UZsize_ntbf2(.a (dtu_fcl_nextthr_bf[2]), |
---|
3282 | .z (nextthr_bf_buf[2])); |
---|
3283 | bw_u1_buf_20x UZsize_ntbf3(.a (dtu_fcl_nextthr_bf[3]), |
---|
3284 | .z (nextthr_bf_buf[3])); |
---|
3285 | // use 6x |
---|
3286 | assign fcl_fdp_next_ctxt_bf_l[2:0] = ~nextthr_bf_buf[2:0] | {3{rst_tri_en}}; |
---|
3287 | assign fcl_fdp_next_ctxt_bf_l[3] = ~nextthr_bf_buf[3] & ~rst_tri_en; |
---|
3288 | |
---|
3289 | // assign nextthr_final_bf = switch_bf ? dtu_fcl_nextthr_bf : thr_f; |
---|
3290 | wire [3:0] nextthr_final_bf_l; |
---|
3291 | bw_u1_muxi21_2x UZfix_ntfmux0(.z (nextthr_final_bf_l[0]), |
---|
3292 | .d0 (thr_f[0]), |
---|
3293 | .d1 (dtu_fcl_nextthr_bf[0]), |
---|
3294 | .s (switch_bf)); |
---|
3295 | bw_u1_inv_8x UZsize_ntfin_buf0(.z (nextthr_final_bf[0]), |
---|
3296 | .a (nextthr_final_bf_l[0])); |
---|
3297 | |
---|
3298 | bw_u1_muxi21_2x UZfix_ntfmux1(.z (nextthr_final_bf_l[1]), |
---|
3299 | .d0 (thr_f[1]), |
---|
3300 | .d1 (dtu_fcl_nextthr_bf[1]), |
---|
3301 | .s (switch_bf)); |
---|
3302 | bw_u1_inv_8x UZsize_ntfin_buf1(.z (nextthr_final_bf[1]), |
---|
3303 | .a (nextthr_final_bf_l[1])); |
---|
3304 | |
---|
3305 | bw_u1_muxi21_2x UZfix_ntfmux2(.z (nextthr_final_bf_l[2]), |
---|
3306 | .d0 (thr_f[2]), |
---|
3307 | .d1 (dtu_fcl_nextthr_bf[2]), |
---|
3308 | .s (switch_bf)); |
---|
3309 | bw_u1_inv_8x UZsize_ntfin_buf2(.z (nextthr_final_bf[2]), |
---|
3310 | .a (nextthr_final_bf_l[2])); |
---|
3311 | |
---|
3312 | bw_u1_muxi21_2x UZfix_ntfmux3(.z (nextthr_final_bf_l[3]), |
---|
3313 | .d0 (thr_f[3]), |
---|
3314 | .d1 (dtu_fcl_nextthr_bf[3]), |
---|
3315 | .s (switch_bf)); |
---|
3316 | bw_u1_inv_8x UZsize_ntfin_buf3(.z (nextthr_final_bf[3]), |
---|
3317 | .a (nextthr_final_bf_l[3])); |
---|
3318 | |
---|
3319 | |
---|
3320 | // decode trap thread |
---|
3321 | dff_s #(2) ld_trp_reg(.din ({tlu_ifu_trappc_vld_w1, |
---|
3322 | tlu_ifu_trapnpc_vld_w1}), |
---|
3323 | .q ({trappc_vld_w2, |
---|
3324 | trapnpc_vld_w2}), |
---|
3325 | .clk (clk), .se(se), .si(), .so()); |
---|
3326 | |
---|
3327 | dff_s #(2) trp_tid_reg(.din (tlu_ifu_trap_tid_w1[1:0]), |
---|
3328 | .q (trap_tid_w2[1:0]), |
---|
3329 | .clk (clk), .se(se), .si(), .so()); |
---|
3330 | |
---|
3331 | assign trap_thr[0] = ~trap_tid_w2[1] & ~trap_tid_w2[0]; |
---|
3332 | assign trap_thr[1] = ~trap_tid_w2[1] & trap_tid_w2[0]; |
---|
3333 | assign trap_thr[2] = trap_tid_w2[1] & ~trap_tid_w2[0]; |
---|
3334 | assign trap_thr[3] = trap_tid_w2[1] & trap_tid_w2[0]; |
---|
3335 | |
---|
3336 | assign load_tpc[3:0] = {4{trappc_vld_w2}} & trap_thr | |
---|
3337 | rb_w2 | |
---|
3338 | {4{rb_stg_w | ims_flush_coll_w}} & thr_w | |
---|
3339 | // {4{dec_fcl_kill4sta_e}} & thr_e | |
---|
3340 | {4{flush_sonly_qual_m}} & thr_m; |
---|
3341 | |
---|
3342 | assign load_bpc[3:0] = {4{brtaken_buf_e}} & thr_e; |
---|
3343 | assign load_pcp4[3:0] = {4{~part_stall_thisthr_f & |
---|
3344 | ~iferrto_thisthr_d1 | |
---|
3345 | arst_vld_f | |
---|
3346 | async_intr_vld_s}} & thr_f; |
---|
3347 | |
---|
3348 | always @ (/*AUTOSENSE*/load_bpc or load_pcp4 or load_tpc) |
---|
3349 | begin |
---|
3350 | // if (fcl_reset) |
---|
3351 | // begin // RESET PC is loaded to T0 |
---|
3352 | // fcl_fdp_tpcbf_sel_old_bf_l = 4'b0001; |
---|
3353 | // fcl_fdp_tpcbf_sel_pcp4_bf_l = 4'b1110; |
---|
3354 | // fcl_fdp_tpcbf_sel_trap_bf_l = 4'b1111; |
---|
3355 | // fcl_fdp_tpcbf_sel_brpc_bf_l = 4'b1111; |
---|
3356 | // end // if (reset) |
---|
3357 | // else |
---|
3358 | // begin |
---|
3359 | fcl_fdp_tpcbf_sel_old_bf_l = (load_bpc | load_tpc | load_pcp4); |
---|
3360 | fcl_fdp_tpcbf_sel_brpc_bf_l = ~load_bpc | load_tpc | load_pcp4; |
---|
3361 | fcl_fdp_tpcbf_sel_pcp4_bf_l = ~load_pcp4 | load_tpc; |
---|
3362 | fcl_fdp_tpcbf_sel_trap_bf_l = ~load_tpc; |
---|
3363 | end // always @ (... |
---|
3364 | |
---|
3365 | // Track correctible errors |
---|
3366 | assign irf_ce_m = exu_ifu_ecc_ce_m & ~trap_m & inst_vld_m & ~kill_curr_m; |
---|
3367 | dff_s #(1) irfcew_ff(.din (irf_ce_m), |
---|
3368 | .q (irf_ce_w), |
---|
3369 | .clk (clk), .se(se), .si(), .so()); |
---|
3370 | |
---|
3371 | // track if ldhit was actually a miss |
---|
3372 | // D and S stage are rolled back through the normal D stage retract |
---|
3373 | // process. |
---|
3374 | assign mark4rb_d = lsu_ifu_dc_parity_error_w2 & thr_match_dw2 & |
---|
3375 | (inst_vld_d | intr_vld_d); |
---|
3376 | assign mark4rb_s = lsu_ifu_dc_parity_error_w2 & thr_match_fw2 & |
---|
3377 | (inst_vld_s | intr_vld_s); |
---|
3378 | |
---|
3379 | assign mark4rb_e = lsu_ifu_dc_parity_error_w2 & thr_match_ew2 & |
---|
3380 | (inst_vld_e | intr_vld_e) & |
---|
3381 | ~dtu_inst_anull_e & ~kill_curr_e; |
---|
3382 | |
---|
3383 | dff_s #(2) markrb_reg(.din ({mark4rb_m, |
---|
3384 | mark4rb_e}), |
---|
3385 | .q ({mark4rb_w, |
---|
3386 | mark4rb_m}), |
---|
3387 | .clk (clk), |
---|
3388 | .se (se), .si(), .so()); |
---|
3389 | |
---|
3390 | // Rollback from W on irf/frf ce and on a dcache parity error |
---|
3391 | assign rb_stg_w = irf_ce_w & inst_vld_w & no_iftrap_w | |
---|
3392 | ffu_ifu_fst_ce_w & inst_vld_w & no_iftrap_w | |
---|
3393 | rb_intr_w & intr_vld_w | |
---|
3394 | mark4rb_w | |
---|
3395 | fcl_dtu_resum_thr_w | |
---|
3396 | fcl_dtu_nuke_thr_w; |
---|
3397 | |
---|
3398 | // flush after hardware micro trap |
---|
3399 | // assign ifu_tlu_flush_w = irf_ce_w | fcl_dtu_nuke_thr_w | mark4rb_w | |
---|
3400 | // fcl_dtu_resum_thr_w; |
---|
3401 | // very critical |
---|
3402 | assign ifu_tlu_flush_m = (exu_ifu_ecc_ce_m & inst_vld_m & ~trap_m | |
---|
3403 | (resumint_m | nuke_thr_m) & |
---|
3404 | intr_vld_m & ~rstint_m | |
---|
3405 | rb_intr_m | |
---|
3406 | mark4rb_m); |
---|
3407 | assign utrap_flush_m = ifu_tlu_flush_m & ~kill_local_m; |
---|
3408 | dff_s #(1) flw_ff(.din (utrap_flush_m), |
---|
3409 | .q (utrap_flush_w), |
---|
3410 | .clk (clk), .se(se), .si(), .so()); |
---|
3411 | assign ifu_tlu_flush_w = utrap_flush_w; |
---|
3412 | assign fcl_swl_flush_w = (irf_ce_w & inst_vld_w & no_iftrap_w | |
---|
3413 | rb_intr_w & intr_vld_w | |
---|
3414 | mark4rb_w | |
---|
3415 | fcl_dtu_resum_thr_w | |
---|
3416 | fcl_dtu_nuke_thr_w); |
---|
3417 | |
---|
3418 | // tells swl to flush and then wake up |
---|
3419 | assign fcl_swl_flush_wake_w = fcl_swl_flush_w & ~mark4rb_w; |
---|
3420 | |
---|
3421 | // if the same instruction keeps hitting ce's disable ce detection |
---|
3422 | // count how many ce's occur to a given thread |
---|
3423 | assign any_ce_w = ffu_ifu_fst_ce_w | irf_ce_w; |
---|
3424 | |
---|
3425 | assign ce_cnt1_nxt = (({4{any_ce_w & inst_vld_w}} & thr_w & |
---|
3426 | ce_cnt0) ^ ce_cnt1) & ~ce_cnt_rst; |
---|
3427 | assign ce_cnt0_nxt = (({4{any_ce_w & inst_vld_w}} & thr_w) ^ |
---|
3428 | ce_cnt0) & ~ce_cnt_rst; |
---|
3429 | |
---|
3430 | assign ce_cnt_rst = thr_w & {4{inst_vld_w & ~any_ce_w}} | {4{fcl_reset}}; |
---|
3431 | |
---|
3432 | dff_s #(8) cecnt_reg(.din ({ce_cnt1_nxt, ce_cnt0_nxt}), |
---|
3433 | .q ({ce_cnt1, ce_cnt0}), |
---|
3434 | .clk (clk), |
---|
3435 | .se(se), .si(), .so()); |
---|
3436 | |
---|
3437 | // find the count for the current d stage thread |
---|
3438 | assign ce_val1_d = (thr_d[0] & ce_cnt1[0] | |
---|
3439 | thr_d[1] & ce_cnt1[1] | |
---|
3440 | thr_d[2] & ce_cnt1[2] | |
---|
3441 | thr_d[3] & ce_cnt1[3]); |
---|
3442 | |
---|
3443 | assign ce_val0_d = (thr_d[0] & ce_cnt0[0] | |
---|
3444 | thr_d[1] & ce_cnt0[1] | |
---|
3445 | thr_d[2] & ce_cnt0[2] | |
---|
3446 | thr_d[3] & ce_cnt0[3]); |
---|
3447 | |
---|
3448 | // if count hits 3 disable ce's |
---|
3449 | assign disable_ce_d = ce_val1_d & ce_val0_d; |
---|
3450 | |
---|
3451 | dff_s #(1) disce_ff(.din (disable_ce_d), |
---|
3452 | .q (disable_ce_e), |
---|
3453 | .clk (clk), .se(se), .si(), .so()); |
---|
3454 | assign ifu_exu_disable_ce_e = disable_ce_e; |
---|
3455 | |
---|
3456 | // select error/trap/utrap rollback PC |
---|
3457 | assign fcl_fdp_trrbpc_sel_trap_bf_l = |
---|
3458 | ~({4{trappc_vld_w2}} & trap_thr); |
---|
3459 | |
---|
3460 | assign fcl_fdp_trrbpc_sel_err_bf_l = |
---|
3461 | ({4{trappc_vld_w2}} & trap_thr) | |
---|
3462 | ~({4{rb_stg_w}} & thr_w); |
---|
3463 | |
---|
3464 | assign fcl_fdp_trrbpc_sel_rb_bf_l = |
---|
3465 | ({4{trappc_vld_w2}} & trap_thr) | |
---|
3466 | ({4{rb_stg_w}} & thr_w) | |
---|
3467 | ~(rb_frome & rb_fromd); |
---|
3468 | |
---|
3469 | assign fcl_fdp_trrbpc_sel_pcs_bf_l = |
---|
3470 | ({4{trappc_vld_w2}} & trap_thr) | |
---|
3471 | ({4{rb_stg_w}} & thr_w) | |
---|
3472 | (rb_frome & rb_fromd); |
---|
3473 | |
---|
3474 | // select next S stage Thr PC |
---|
3475 | assign fcl_fdp_nextpcs_sel_pce_f_l = ~rb_frome; |
---|
3476 | assign fcl_fdp_nextpcs_sel_pcd_f_l = rb_frome | ~rb_fromd; |
---|
3477 | assign fcl_fdp_nextpcs_sel_pcf_f_l = rb_frome | rb_fromd | |
---|
3478 | ~(thr_f & {4{~part_stall_thisthr_f & |
---|
3479 | ~iferrto_thisthr_d1 | |
---|
3480 | arst_vld_f | |
---|
3481 | async_intr_vld_s}}); |
---|
3482 | assign fcl_fdp_nextpcs_sel_pcs_f_l = rb_frome | rb_fromd | |
---|
3483 | (thr_f & {4{~part_stall_thisthr_f & |
---|
3484 | ~iferrto_thisthr_d1 | |
---|
3485 | arst_vld_f | |
---|
3486 | async_intr_vld_s}}); |
---|
3487 | |
---|
3488 | // next S2 stage pc and npc select |
---|
3489 | assign thr_f_dec[3:1] = thr_f_crit[3:1] & {3{~rst_tri_en}}; |
---|
3490 | assign thr_f_dec[0] = thr_f_crit[0] | rst_tri_en; |
---|
3491 | assign fcl_fdp_thr_s2_l = ~thr_f_dec; // thr_f = thr_s2 |
---|
3492 | |
---|
3493 | |
---|
3494 | // Select NextPC from |
---|
3495 | // 1. Trap NextPC (if the tnpc is valid) |
---|
3496 | // 2. reset PC |
---|
3497 | // 3. incremented PC (PC+4) |
---|
3498 | // 4. old PC (in the event of a stall) |
---|
3499 | |
---|
3500 | // Load the trap PC to the BF stage NPC. (The BF stage NPC is used |
---|
3501 | // only for storing the next PC from the TLU |
---|
3502 | assign fcl_fdp_thrtnpc_sel_tnpc_l = ~({4{trapnpc_vld_w2}} & trap_thr); |
---|
3503 | |
---|
3504 | assign fcl_fdp_thrtnpc_sel_npcw_l = ({4{trapnpc_vld_w2}} & trap_thr) | |
---|
3505 | ~({4{rb_stg_w}} & thr_w); |
---|
3506 | |
---|
3507 | assign fcl_fdp_thrtnpc_sel_pcf_l = ({4{trapnpc_vld_w2}} & trap_thr) | |
---|
3508 | ({4{rb_stg_w}} & thr_w) | |
---|
3509 | (~({4{ims_flush_coll_w}} & thr_w) & |
---|
3510 | ~({4{flush_sonly_qual_m}} & thr_m)); |
---|
3511 | // {4{dec_fcl_kill4sta_e}} & thr_e); |
---|
3512 | |
---|
3513 | assign fcl_fdp_thrtnpc_sel_old_l = ({4{trapnpc_vld_w2}} & trap_thr) | |
---|
3514 | ({4{rb_stg_w}} & thr_w) | |
---|
3515 | ({4{ims_flush_coll_w}} & thr_w) | |
---|
3516 | ({4{flush_sonly_qual_m}} & thr_m); |
---|
3517 | // {4{dec_fcl_kill4sta_e}} & thr_e); |
---|
3518 | |
---|
3519 | assign ntpc_vld_nxt = fcl_fdp_thrtnpc_sel_old_l | |
---|
3520 | ntpc_vld & ({4{(part_stall_thisthr_f | |
---|
3521 | iferrto_thisthr_d1) & |
---|
3522 | ~arst_vld_f & |
---|
3523 | ~async_intr_vld_s}} | ~thr_f) & |
---|
3524 | ~({4{trappc_vld_w2}} & trap_thr); |
---|
3525 | |
---|
3526 | dffr_s #(4) ntpcv_reg(.din (ntpc_vld_nxt), |
---|
3527 | .clk (clk), |
---|
3528 | .q (ntpc_vld), |
---|
3529 | .rst (fcl_reset), |
---|
3530 | .se (se), .si(), .so()); |
---|
3531 | |
---|
3532 | assign ntpc_thisthr = (thr_f[0] & ntpc_vld[0] | |
---|
3533 | thr_f[1] & ntpc_vld[1] | |
---|
3534 | thr_f[2] & ntpc_vld[2] | |
---|
3535 | thr_f[3] & ntpc_vld[3]); |
---|
3536 | |
---|
3537 | // assign fcl_fdp_noswpc_sel_rst_l_bf = 1'b1; |
---|
3538 | assign fcl_fdp_noswpc_sel_tnpc_l_bf = ~ntpc_thisthr; |
---|
3539 | assign fcl_fdp_noswpc_sel_old_l_bf = ntpc_thisthr | inst_vld_f | arst_vld_f; |
---|
3540 | assign fcl_fdp_noswpc_sel_inc_l_bf = ntpc_thisthr | ~inst_vld_f & ~arst_vld_f; |
---|
3541 | |
---|
3542 | |
---|
3543 | // Don't need noswpc_sel_old anymore (this is always 1) |
---|
3544 | // always @(/*AUTOSENSE*/ntpc_vld or reset or thr_f) |
---|
3545 | // begin |
---|
3546 | // if (reset) |
---|
3547 | // begin |
---|
3548 | // fcl_fdp_noswpc_sel_tnpc_l_bf = 1'b1; |
---|
3549 | // fcl_fdp_noswpc_sel_rst_l_bf = 1'b0; |
---|
3550 | // fcl_fdp_noswpc_sel_inc_l_bf = 1'b1; |
---|
3551 | // fcl_fdp_noswpc_sel_old_l_bf = 1'b1; |
---|
3552 | // end |
---|
3553 | // else if ((ntpc_vld & thr_f) != 4'b0000) |
---|
3554 | // begin |
---|
3555 | // fcl_fdp_noswpc_sel_tnpc_l_bf = 1'b0; |
---|
3556 | // fcl_fdp_noswpc_sel_rst_l_bf = 1'b1; |
---|
3557 | // fcl_fdp_noswpc_sel_inc_l_bf = 1'b1; |
---|
3558 | // fcl_fdp_noswpc_sel_old_l_bf = 1'b1; |
---|
3559 | // end // if ((ntpc_vld & thr_f) != 4'b0000) |
---|
3560 | //// else if (ely_stall_thisthr_f) |
---|
3561 | //// begin |
---|
3562 | //// fcl_fdp_noswpc_sel_tnpc_l_bf = 1'b1; |
---|
3563 | //// fcl_fdp_noswpc_sel_rst_l_bf = 1'b1; |
---|
3564 | //// fcl_fdp_noswpc_sel_inc_l_bf = 1'b1; |
---|
3565 | //// fcl_fdp_noswpc_sel_old_l_bf = 1'b0; |
---|
3566 | //// end // if (ely_stall_thisthr_f) |
---|
3567 | // else |
---|
3568 | // begin |
---|
3569 | // fcl_fdp_noswpc_sel_tnpc_l_bf = 1'b1; |
---|
3570 | // fcl_fdp_noswpc_sel_rst_l_bf = 1'b1; |
---|
3571 | // fcl_fdp_noswpc_sel_inc_l_bf = 1'b0; |
---|
3572 | // fcl_fdp_noswpc_sel_old_l_bf = 1'b1; |
---|
3573 | // end // else: |
---|
3574 | // |
---|
3575 | // end // always @ (... |
---|
3576 | |
---|
3577 | // NOTE: direct branch vs indirect branch select goes from dtu to fdp |
---|
3578 | |
---|
3579 | //---------------------------------------------------------------------- |
---|
3580 | // Instruction Register Related Control |
---|
3581 | //---------------------------------------------------------------------- |
---|
3582 | |
---|
3583 | // use NIR if no read previously |
---|
3584 | assign fcl_fdp_usenir_sel_nir_s1 = usenir_s1; |
---|
3585 | |
---|
3586 | |
---|
3587 | assign fcl_fdp_inst_sel_nop_s_l = ~(ely_stall_thisthr_f | |
---|
3588 | ~inst_vld_s_crit | |
---|
3589 | force_intr_s | |
---|
3590 | immu_fault_f); |
---|
3591 | |
---|
3592 | assign fcl_fdp_inst_sel_switch_s_l = ~switch_s2 | |
---|
3593 | (ely_stall_thisthr_f | |
---|
3594 | ~inst_vld_s_crit | |
---|
3595 | force_intr_s | |
---|
3596 | immu_fault_f); |
---|
3597 | |
---|
3598 | assign fcl_fdp_inst_sel_nir_s_l = ~usenir_s1 | |
---|
3599 | (switch_s2 | |
---|
3600 | ely_stall_thisthr_f | |
---|
3601 | ~inst_vld_s_crit | |
---|
3602 | force_intr_s | |
---|
3603 | immu_fault_f); |
---|
3604 | |
---|
3605 | assign fcl_fdp_inst_sel_curr_s_l = (usenir_s1 | |
---|
3606 | switch_s2 | |
---|
3607 | ely_stall_thisthr_f | |
---|
3608 | ~inst_vld_s_crit | |
---|
3609 | force_intr_s | |
---|
3610 | immu_fault_f); |
---|
3611 | |
---|
3612 | |
---|
3613 | // Instruction Output Mux |
---|
3614 | // always @ (/*AUTOSENSE*/ely_stall_thisthr_f or force_intr_s |
---|
3615 | // or immu_fault_f or inst_vld_s_crit or switch_s2 |
---|
3616 | // or usenir_s1) |
---|
3617 | // begin |
---|
3618 | // if (ely_stall_thisthr_f | ~inst_vld_s_crit | force_intr_s | |
---|
3619 | // immu_fault_f) |
---|
3620 | // begin // stalled or imiss |
---|
3621 | // fcl_fdp_inst_sel_nop_s_l = 1'b0; |
---|
3622 | // fcl_fdp_inst_sel_switch_s_l = 1'b1; |
---|
3623 | // fcl_fdp_inst_sel_nir_s_l = 1'b1; |
---|
3624 | // fcl_fdp_inst_sel_curr_s_l = 1'b1; |
---|
3625 | // end |
---|
3626 | // else if (switch_s2) |
---|
3627 | // begin |
---|
3628 | // fcl_fdp_inst_sel_nop_s_l = 1'b1; |
---|
3629 | // fcl_fdp_inst_sel_switch_s_l = 1'b0; |
---|
3630 | // fcl_fdp_inst_sel_nir_s_l = 1'b1; |
---|
3631 | // fcl_fdp_inst_sel_curr_s_l = 1'b1; |
---|
3632 | // end |
---|
3633 | // else if (usenir_s1) |
---|
3634 | // begin |
---|
3635 | // fcl_fdp_inst_sel_nop_s_l = 1'b1; |
---|
3636 | // fcl_fdp_inst_sel_switch_s_l = 1'b1; |
---|
3637 | // fcl_fdp_inst_sel_nir_s_l = 1'b0; |
---|
3638 | // fcl_fdp_inst_sel_curr_s_l = 1'b1; |
---|
3639 | // end |
---|
3640 | // else |
---|
3641 | // begin |
---|
3642 | // fcl_fdp_inst_sel_nop_s_l = 1'b1; |
---|
3643 | // fcl_fdp_inst_sel_switch_s_l = 1'b1; |
---|
3644 | // fcl_fdp_inst_sel_nir_s_l = 1'b1; |
---|
3645 | // fcl_fdp_inst_sel_curr_s_l = 1'b0; |
---|
3646 | // end // else: !if(switch_s2 | stall_s1) |
---|
3647 | // end // always @ (... |
---|
3648 | |
---|
3649 | // thread IR input muxes |
---|
3650 | assign fcl_fdp_tinst_sel_rb_s_l = ~rb_w2; |
---|
3651 | assign fcl_fdp_tinst_sel_ifq_s_l = rb_w2 | ~ifq_fcl_fill_thr; |
---|
3652 | assign fcl_fdp_tinst_sel_curr_s_l = ~val_thr_s1 | rb_w2 | ifq_fcl_fill_thr; |
---|
3653 | assign fcl_fdp_tinst_sel_old_s_l = val_thr_s1 | rb_w2 | ifq_fcl_fill_thr; |
---|
3654 | |
---|
3655 | // Select rollback instruction |
---|
3656 | assign fcl_fdp_rbinst_sel_inste_s = {4{rb2_inst_e | rt2_inst_e}} & |
---|
3657 | thr_e; |
---|
3658 | |
---|
3659 | // thread NIR input muxes (2:1 no need to protect) |
---|
3660 | assign fcl_fdp_thr_s1_l = ~thr_s1 | {4{stall_s1}}; |
---|
3661 | |
---|
3662 | // select appropriate NIR |
---|
3663 | assign dec_thr_s1_l[0] = ~(thr_s1[0] | rst_tri_en); |
---|
3664 | assign dec_thr_s1_l[3:1] = ~(thr_s1[3:1] & {3{~rst_tri_en}}); |
---|
3665 | |
---|
3666 | assign fcl_fdp_nirthr_s1_l = dec_thr_s1_l; |
---|
3667 | |
---|
3668 | |
---|
3669 | //-------------------- |
---|
3670 | // rdsr data to exu |
---|
3671 | //-------------------- |
---|
3672 | |
---|
3673 | dff_s #(1) pcrsr_ff(.din (dec_fcl_rdsr_sel_pc_d), |
---|
3674 | .clk (clk), |
---|
3675 | .q (rdsr_sel_pc_e), |
---|
3676 | .se (se), .si(), .so()); |
---|
3677 | dff_s #(1) thrrsr_ff(.din (dec_fcl_rdsr_sel_thr_d), |
---|
3678 | .clk (clk), |
---|
3679 | .q (rdsr_sel_thr_e), |
---|
3680 | .se (se), .si(), .so()); |
---|
3681 | // make sure they are exclusive |
---|
3682 | assign fcl_fdp_rdsr_sel_pc_e_l = ~rdsr_sel_pc_e; |
---|
3683 | assign fcl_fdp_rdsr_sel_thr_e_l = ~(~rdsr_sel_pc_e & rdsr_sel_thr_e); |
---|
3684 | assign fcl_fdp_rdsr_sel_ver_e_l = ~(~rdsr_sel_pc_e & ~rdsr_sel_thr_e); |
---|
3685 | |
---|
3686 | //-------------------------------------------------------------- |
---|
3687 | // Reg file control |
---|
3688 | //-------------------------------------------------------------- |
---|
3689 | |
---|
3690 | // Some decode is done here since these signals are in the crit path |
---|
3691 | |
---|
3692 | // Regfile enables are only power saving features. So they don't |
---|
3693 | // have to be exact, as long as they are on, a super set of when |
---|
3694 | // they need to be on. |
---|
3695 | |
---|
3696 | // Enable rs3 if store or atomic or mov |
---|
3697 | assign ifu_exu_ren3_s = inst_vld_f & fdp_fcl_op_s[1] & fdp_fcl_op3_s[2] & |
---|
3698 | (fdp_fcl_op_s[0] | fdp_fcl_op3_s[5]); |
---|
3699 | |
---|
3700 | // enable rs2 if i=0 and !branch or CAS |
---|
3701 | // cas not fully decoded; i=inst[13]; |
---|
3702 | assign ifu_exu_ren2_s = inst_vld_f & fdp_fcl_op_s[1] & |
---|
3703 | (~fdp_fcl_ibit_s | |
---|
3704 | fdp_fcl_op_s[0] & fdp_fcl_op3_s[5]); |
---|
3705 | |
---|
3706 | // rs1 is read if this is not (a branch on cc or no-op/sethi) |
---|
3707 | assign ifu_exu_ren1_s = inst_vld_f & (fdp_fcl_op_s[1] | // not br/call |
---|
3708 | fdp_fcl_op3_s[4] & fdp_fcl_op3_s[3]); // BPR |
---|
3709 | |
---|
3710 | //------------------------------------- |
---|
3711 | // Generate oddwin signal for rs and rd |
---|
3712 | //------------------------------------- |
---|
3713 | assign fcl_fdp_oddwin_s = (exu_ifu_oddwin_s[0] & thr_f[0] | |
---|
3714 | exu_ifu_oddwin_s[1] & thr_f[1] | |
---|
3715 | exu_ifu_oddwin_s[2] & thr_f[2] | |
---|
3716 | exu_ifu_oddwin_s[3] & thr_f[3]); |
---|
3717 | |
---|
3718 | dff_s #(1) oddwin_ff(.din (fcl_fdp_oddwin_s), |
---|
3719 | .clk (clk), |
---|
3720 | .q (fcl_imd_oddwin_d), |
---|
3721 | .se (se), .si(), .so()); |
---|
3722 | |
---|
3723 | |
---|
3724 | sink #(2) s0(.in (sas_thrid_w)); |
---|
3725 | endmodule // sparc_ifu_fcl |
---|