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