Line data Source code
1 : //********************************************************************************
2 : // SPDX-License-Identifier: Apache-2.0
3 : // Copyright 2020 Western Digital Corporation or its affiliates.
4 : //
5 : // Licensed under the Apache License, Version 2.0 (the "License");
6 : // you may not use this file except in compliance with the License.
7 : // You may obtain a copy of the License at
8 : //
9 : // http://www.apache.org/licenses/LICENSE-2.0
10 : //
11 : // Unless required by applicable law or agreed to in writing, software
12 : // distributed under the License is distributed on an "AS IS" BASIS,
13 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 : // See the License for the specific language governing permissions and
15 : // limitations under the License.
16 : //********************************************************************************
17 :
18 : //********************************************************************************
19 : // Function: Instruction aligner
20 : //********************************************************************************
21 : module el2_ifu_aln_ctl
22 : import el2_pkg::*;
23 : #(
24 : `include "el2_param.vh"
25 : )
26 : (
27 :
28 0 : input logic scan_mode, // Flop scan mode control
29 338 : input logic rst_l, // reset, active low
30 69890155 : input logic clk, // Clock only while core active. Through one clock header. For flops with second clock header built in. Connected to ACTIVE_L2CLK.
31 69890155 : input logic active_clk, // Clock only while core active. Through two clock headers. For flops without second clock header built in.
32 :
33 8 : input logic ifu_async_error_start, // ecc/parity related errors with current fetch - not sent down the pipe
34 :
35 4 : input logic [1:0] iccm_rd_ecc_double_err, // This fetch has a double ICCM ecc error.
36 :
37 182 : input logic [1:0] ic_access_fault_f, // Instruction access fault for the current fetch.
38 172 : input logic [1:0] ic_access_fault_type_f, // Instruction access fault types
39 :
40 674202 : input logic exu_flush_final, // Flush from the pipeline.
41 :
42 6203297 : input logic dec_i0_decode_d, // Valid instruction at D-stage and not blocked
43 :
44 2168046 : input logic [31:0] ifu_fetch_data_f, // fetch data in memory format - not right justified
45 :
46 6340267 : input logic [1:0] ifu_fetch_val, // valids on a 2B boundary, right justified
47 444 : input logic [31:1] ifu_fetch_pc, // starting pc of fetch
48 :
49 :
50 :
51 6018075 : output logic ifu_i0_valid, // Instruction 0 is valid
52 208 : output logic ifu_i0_icaf, // Instruction 0 has access fault
53 274 : output logic [1:0] ifu_i0_icaf_type, // Instruction 0 access fault type
54 86 : output logic ifu_i0_icaf_second, // Instruction 0 has access fault on second 2B of 4B inst
55 :
56 2 : output logic ifu_i0_dbecc, // Instruction 0 has double bit ecc error
57 468826 : output logic [31:0] ifu_i0_instr, // Instruction 0
58 1322 : output logic [31:1] ifu_i0_pc, // Instruction 0 PC
59 5774060 : output logic ifu_i0_pc4,
60 :
61 5994101 : output logic ifu_fb_consume1, // Consumed one buffer. To fetch control fetch for buffer mass balance
62 1761864 : output logic ifu_fb_consume2, // Consumed two buffers.To fetch control fetch for buffer mass balance
63 :
64 :
65 376935 : input logic [pt.BHT_GHR_SIZE-1:0] ifu_bp_fghr_f, // fetch GHR
66 518791 : input logic [31:1] ifu_bp_btb_target_f, // predicted RET target
67 2177331 : input logic [11:0] ifu_bp_poffset_f, // predicted target offset
68 0 : input logic [1:0] [$clog2(pt.BTB_SIZE)-1:0] ifu_bp_fa_index_f, // predicted branch index (fully associative option)
69 :
70 1824638 : input logic [1:0] ifu_bp_hist0_f, // history counters for all 4 potential branches, bit 1, right justified
71 2025808 : input logic [1:0] ifu_bp_hist1_f, // history counters for all 4 potential branches, bit 1, right justified
72 408833 : input logic [1:0] ifu_bp_pc4_f, // pc4 indication, right justified
73 2375527 : input logic [1:0] ifu_bp_way_f, // way indication, right justified
74 957477 : input logic [1:0] ifu_bp_valid_f, // branch valid, right justified
75 70466 : input logic [1:0] ifu_bp_ret_f, // predicted ret indication, right justified
76 :
77 :
78 206674 : output el2_br_pkt_t i0_brp, // Branch packet for I0.
79 651206 : output logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] ifu_i0_bp_index, // BP index
80 631071 : output logic [pt.BHT_GHR_SIZE-1:0] ifu_i0_bp_fghr, // BP FGHR
81 21223 : output logic [pt.BTB_BTAG_SIZE-1:0] ifu_i0_bp_btag, // BP tag
82 :
83 0 : output logic [$clog2(pt.BTB_SIZE)-1:0] ifu_i0_fa_index, // Fully associt btb index
84 :
85 6203297 : output logic ifu_pmu_instr_aligned, // number of inst aligned this cycle
86 :
87 1428516 : output logic [15:0] ifu_i0_cinst // 16b compress inst for i0
88 : );
89 :
90 :
91 :
92 6789925 : logic ifvalid;
93 51596 : logic shift_f1_f0, shift_f2_f0, shift_f2_f1;
94 271302 : logic fetch_to_f0, fetch_to_f1, fetch_to_f2;
95 :
96 686018 : logic [1:0] f2val_in, f2val;
97 1524653 : logic [1:0] f1val_in, f1val;
98 4315925 : logic [1:0] f0val_in, f0val;
99 77543 : logic [1:0] sf1val, sf0val;
100 :
101 1362290 : logic [31:0] aligndata;
102 5774061 : logic first4B, first2B;
103 :
104 241480 : logic [31:0] uncompress0;
105 6203297 : logic i0_shift;
106 4373825 : logic shift_2B, shift_4B;
107 3313797 : logic f1_shift_2B;
108 580546 : logic f2_valid, sf1_valid, sf0_valid;
109 :
110 1362290 : logic [31:0] ifirst;
111 4651862 : logic [1:0] alignval;
112 2131884 : logic [31:1] firstpc, secondpc;
113 :
114 2078659 : logic [11:0] f1poffset;
115 554770 : logic [11:0] f0poffset;
116 395787 : logic [pt.BHT_GHR_SIZE-1:0] f1fghr;
117 605466 : logic [pt.BHT_GHR_SIZE-1:0] f0fghr;
118 1873921 : logic [1:0] f1hist1;
119 2526533 : logic [1:0] f0hist1;
120 1630953 : logic [1:0] f1hist0;
121 2345377 : logic [1:0] f0hist0;
122 :
123 0 : logic [1:0][$clog2(pt.BTB_SIZE)-1:0] f0index, f1index, alignindex;
124 :
125 126 : logic [1:0] f1ictype;
126 188 : logic [1:0] f0ictype;
127 :
128 310966 : logic [1:0] f1pc4;
129 477438 : logic [1:0] f0pc4;
130 :
131 13698 : logic [1:0] f1ret;
132 79396 : logic [1:0] f0ret;
133 3408119 : logic [1:0] f1way;
134 3983868 : logic [1:0] f0way;
135 :
136 514013 : logic [1:0] f1brend;
137 804303 : logic [1:0] f0brend;
138 :
139 2271372 : logic [1:0] alignbrend;
140 2126596 : logic [1:0] alignpc4;
141 :
142 81926 : logic [1:0] alignret;
143 4381882 : logic [1:0] alignway;
144 4645494 : logic [1:0] alignhist1;
145 4154928 : logic [1:0] alignhist0;
146 4114365 : logic [1:1] alignfromf1;
147 2366603 : logic i0_ends_f1;
148 9628 : logic i0_br_start_error;
149 :
150 381753 : logic [31:1] f1prett;
151 439711 : logic [31:1] f0prett;
152 2 : logic [1:0] f1dbecc;
153 2 : logic [1:0] f0dbecc;
154 134 : logic [1:0] f1icaf;
155 204 : logic [1:0] f0icaf;
156 :
157 2 : logic [1:0] aligndbecc;
158 120 : logic [1:0] alignicaf;
159 2551678 : logic i0_brp_pc4;
160 :
161 611636 : logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] firstpc_hash, secondpc_hash;
162 :
163 0 : logic first_legal;
164 :
165 4433903 : logic [1:0] wrptr, wrptr_in;
166 3628584 : logic [1:0] rdptr, rdptr_in;
167 4278423 : logic [2:0] qwen;
168 321653 : logic [31:0] q2,q1,q0;
169 2752024 : logic q2off_in, q2off;
170 2745403 : logic q1off_in, q1off;
171 2776908 : logic q0off_in, q0off;
172 3740243 : logic f0_shift_2B;
173 :
174 1290842 : logic [31:0] q0eff;
175 900078 : logic [31:0] q0final;
176 4907995 : logic q0ptr;
177 4907995 : logic [1:0] q0sel;
178 :
179 1134404 : logic [31:0] q1eff;
180 1321910 : logic [15:0] q1final;
181 3427642 : logic q1ptr;
182 3427642 : logic [1:0] q1sel;
183 :
184 3628576 : logic [2:0] qren;
185 :
186 1888604 : logic consume_fb1, consume_fb0;
187 122 : logic [1:0] icaf_eff;
188 :
189 : localparam BRDATA_SIZE = pt.BTB_ENABLE ? 16+($clog2(pt.BTB_SIZE)*2*pt.BTB_FULLYA) : 4;
190 : localparam BRDATA_WIDTH = pt.BTB_ENABLE ? 8+($clog2(pt.BTB_SIZE)*pt.BTB_FULLYA) : 2;
191 60957 : logic [BRDATA_SIZE-1:0] brdata_in, brdata2, brdata1, brdata0;
192 193865 : logic [BRDATA_SIZE-1:0] brdata1eff, brdata0eff;
193 179383 : logic [BRDATA_SIZE-1:0] brdata1final, brdata0final;
194 :
195 : localparam MHI = 1+(pt.BTB_ENABLE * (43+pt.BHT_GHR_SIZE));
196 : localparam MSIZE = 2+(pt.BTB_ENABLE * (43+pt.BHT_GHR_SIZE));
197 :
198 144679 : logic [MHI:0] misc_data_in, misc2, misc1, misc0;
199 514127 : logic [MHI:0] misc1eff, misc0eff;
200 :
201 16657 : logic [pt.BTB_BTAG_SIZE-1:0] firstbrtag_hash, secondbrtag_hash;
202 :
203 8 : logic error_stall_in, error_stall;
204 :
205 : assign error_stall_in = (error_stall | ifu_async_error_start) & ~exu_flush_final;
206 :
207 : rvdff #(.WIDTH(7)) bundle1ff (.*,
208 : .clk(active_clk),
209 : .din ({wrptr_in[1:0],rdptr_in[1:0],q2off_in,q1off_in,q0off_in}),
210 : .dout({wrptr[1:0], rdptr[1:0], q2off, q1off, q0off})
211 : );
212 :
213 : rvdffie #(.WIDTH(7),.OVERRIDE(1)) bundle2ff (.*,
214 : .din ({error_stall_in,f2val_in[1:0],f1val_in[1:0],f0val_in[1:0]}),
215 : .dout({error_stall, f2val[1:0], f1val[1:0], f0val[1:0] })
216 : );
217 :
218 : if(pt.BTB_ENABLE==1) begin : genblock1
219 : rvdffe #(BRDATA_SIZE) brdata2ff (.*, .clk(clk), .en(qwen[2]), .din(brdata_in[BRDATA_SIZE-1:0]), .dout(brdata2[BRDATA_SIZE-1:0]));
220 : rvdffe #(BRDATA_SIZE) brdata1ff (.*, .clk(clk), .en(qwen[1]), .din(brdata_in[BRDATA_SIZE-1:0]), .dout(brdata1[BRDATA_SIZE-1:0]));
221 : rvdffe #(BRDATA_SIZE) brdata0ff (.*, .clk(clk), .en(qwen[0]), .din(brdata_in[BRDATA_SIZE-1:0]), .dout(brdata0[BRDATA_SIZE-1:0]));
222 : rvdffe #(MSIZE) misc2ff (.*, .clk(clk), .en(qwen[2]), .din(misc_data_in[MHI:0]), .dout(misc2[MHI:0]));
223 : rvdffe #(MSIZE) misc1ff (.*, .clk(clk), .en(qwen[1]), .din(misc_data_in[MHI:0]), .dout(misc1[MHI:0]));
224 : rvdffe #(MSIZE) misc0ff (.*, .clk(clk), .en(qwen[0]), .din(misc_data_in[MHI:0]), .dout(misc0[MHI:0]));
225 : end
226 : else begin : genblock1
227 :
228 : rvdffie #((MSIZE*3)+(BRDATA_SIZE*3)) miscff (.*,
229 : .din({qwen[2] ? {misc_data_in[MHI:0], brdata_in[BRDATA_SIZE-1:0]} : {misc2[MHI:0], brdata2[BRDATA_SIZE-1:0]},
230 : qwen[1] ? {misc_data_in[MHI:0], brdata_in[BRDATA_SIZE-1:0]} : {misc1[MHI:0], brdata1[BRDATA_SIZE-1:0]},
231 : qwen[0] ? {misc_data_in[MHI:0], brdata_in[BRDATA_SIZE-1:0]} : {misc0[MHI:0], brdata0[BRDATA_SIZE-1:0]}}),
232 : .dout({misc2[MHI:0], brdata2[BRDATA_SIZE-1:0],
233 : misc1[MHI:0], brdata1[BRDATA_SIZE-1:0],
234 : misc0[MHI:0], brdata0[BRDATA_SIZE-1:0]})
235 : );
236 : end
237 :
238 338 : logic [31:1] q2pc, q1pc, q0pc;
239 :
240 : rvdffe #(31) q2pcff (.*, .clk(clk), .en(qwen[2]), .din(ifu_fetch_pc[31:1]), .dout(q2pc[31:1]));
241 : rvdffe #(31) q1pcff (.*, .clk(clk), .en(qwen[1]), .din(ifu_fetch_pc[31:1]), .dout(q1pc[31:1]));
242 : rvdffe #(31) q0pcff (.*, .clk(clk), .en(qwen[0]), .din(ifu_fetch_pc[31:1]), .dout(q0pc[31:1]));
243 :
244 : rvdffe #(32) q2ff (.*, .clk(clk), .en(qwen[2]), .din(ifu_fetch_data_f[31:0]), .dout(q2[31:0]));
245 : rvdffe #(32) q1ff (.*, .clk(clk), .en(qwen[1]), .din(ifu_fetch_data_f[31:0]), .dout(q1[31:0]));
246 : rvdffe #(32) q0ff (.*, .clk(clk), .en(qwen[0]), .din(ifu_fetch_data_f[31:0]), .dout(q0[31:0]));
247 :
248 :
249 : // new queue control logic
250 :
251 : assign qren[2:0] = { rdptr[1:0] == 2'b10,
252 : rdptr[1:0] == 2'b01,
253 : rdptr[1:0] == 2'b00 };
254 :
255 : assign qwen[2:0] = { (wrptr[1:0] == 2'b10) & ifvalid,
256 : (wrptr[1:0] == 2'b01) & ifvalid,
257 : (wrptr[1:0] == 2'b00) & ifvalid };
258 :
259 :
260 : assign rdptr_in[1:0] = ({2{ qren[0] & ifu_fb_consume1 & ~exu_flush_final}} & 2'b01 ) |
261 : ({2{ qren[1] & ifu_fb_consume1 & ~exu_flush_final}} & 2'b10 ) |
262 : ({2{ qren[2] & ifu_fb_consume1 & ~exu_flush_final}} & 2'b00 ) |
263 : ({2{ qren[0] & ifu_fb_consume2 & ~exu_flush_final}} & 2'b10 ) |
264 : ({2{ qren[1] & ifu_fb_consume2 & ~exu_flush_final}} & 2'b00 ) |
265 : ({2{ qren[2] & ifu_fb_consume2 & ~exu_flush_final}} & 2'b01 ) |
266 : ({2{~ifu_fb_consume1 & ~ifu_fb_consume2 & ~exu_flush_final}} & rdptr[1:0]);
267 :
268 : assign wrptr_in[1:0] = ({2{ qwen[0] & ~exu_flush_final}} & 2'b01 ) |
269 : ({2{ qwen[1] & ~exu_flush_final}} & 2'b10 ) |
270 : ({2{ qwen[2] & ~exu_flush_final}} & 2'b00 ) |
271 : ({2{~ifvalid & ~exu_flush_final}} & wrptr[1:0]);
272 :
273 :
274 :
275 : assign q2off_in = ( ~qwen[2] & (rdptr[1:0]==2'd2) & (q2off | f0_shift_2B) ) |
276 : ( ~qwen[2] & (rdptr[1:0]==2'd1) & (q2off | f1_shift_2B) ) |
277 : ( ~qwen[2] & (rdptr[1:0]==2'd0) & q2off );
278 :
279 : assign q1off_in = ( ~qwen[1] & (rdptr[1:0]==2'd1) & (q1off | f0_shift_2B) ) |
280 : ( ~qwen[1] & (rdptr[1:0]==2'd0) & (q1off | f1_shift_2B) ) |
281 : ( ~qwen[1] & (rdptr[1:0]==2'd2) & q1off );
282 :
283 : assign q0off_in = ( ~qwen[0] & (rdptr[1:0]==2'd0) & (q0off | f0_shift_2B) ) |
284 : ( ~qwen[0] & (rdptr[1:0]==2'd2) & (q0off | f1_shift_2B) ) |
285 : ( ~qwen[0] & (rdptr[1:0]==2'd1) & q0off );
286 :
287 :
288 :
289 : assign q0ptr = ( (rdptr[1:0]==2'b00) & q0off ) |
290 : ( (rdptr[1:0]==2'b01) & q1off ) |
291 : ( (rdptr[1:0]==2'b10) & q2off );
292 :
293 : assign q1ptr = ( (rdptr[1:0]==2'b00) & q1off ) |
294 : ( (rdptr[1:0]==2'b01) & q2off ) |
295 : ( (rdptr[1:0]==2'b10) & q0off );
296 :
297 : assign q0sel[1:0] = {q0ptr,~q0ptr};
298 :
299 : assign q1sel[1:0] = {q1ptr,~q1ptr};
300 :
301 : // end new queue control logic
302 :
303 :
304 : // misc data that is associated with each fetch buffer
305 :
306 : if(pt.BTB_ENABLE==1)
307 : assign misc_data_in[MHI:0] = {
308 :
309 : ic_access_fault_type_f[1:0],
310 : ifu_bp_btb_target_f[31:1],
311 : ifu_bp_poffset_f[11:0],
312 : ifu_bp_fghr_f[pt.BHT_GHR_SIZE-1:0]
313 : };
314 : else
315 : assign misc_data_in[MHI:0] = {
316 : ic_access_fault_type_f[1:0]
317 : };
318 :
319 :
320 : assign {misc1eff[MHI:0],misc0eff[MHI:0]} = (({MSIZE*2{qren[0]}} & {misc1[MHI:0],misc0[MHI:0]}) |
321 : ({MSIZE*2{qren[1]}} & {misc2[MHI:0],misc1[MHI:0]}) |
322 : ({MSIZE*2{qren[2]}} & {misc0[MHI:0],misc2[MHI:0]}));
323 :
324 : if(pt.BTB_ENABLE==1) begin
325 : assign {
326 : f1ictype[1:0],
327 : f1prett[31:1],
328 : f1poffset[11:0],
329 : f1fghr[pt.BHT_GHR_SIZE-1:0]
330 : } = misc1eff[MHI:0];
331 :
332 : assign {
333 : f0ictype[1:0],
334 : f0prett[31:1],
335 : f0poffset[11:0],
336 : f0fghr[pt.BHT_GHR_SIZE-1:0]
337 : } = misc0eff[MHI:0];
338 :
339 : if(pt.BTB_FULLYA) begin
340 : assign brdata_in[BRDATA_SIZE-1:0] = {
341 : ifu_bp_fa_index_f[1], iccm_rd_ecc_double_err[1],ic_access_fault_f[1],ifu_bp_hist1_f[1],ifu_bp_hist0_f[1],ifu_bp_pc4_f[1],ifu_bp_way_f[1],ifu_bp_valid_f[1],ifu_bp_ret_f[1],
342 : ifu_bp_fa_index_f[0], iccm_rd_ecc_double_err[0],ic_access_fault_f[0],ifu_bp_hist1_f[0],ifu_bp_hist0_f[0],ifu_bp_pc4_f[0],ifu_bp_way_f[0],ifu_bp_valid_f[0],ifu_bp_ret_f[0]
343 : };
344 : assign {f0index[1],f0dbecc[1],f0icaf[1],f0hist1[1],f0hist0[1],f0pc4[1],f0way[1],f0brend[1],f0ret[1],
345 : f0index[0],f0dbecc[0],f0icaf[0],f0hist1[0],f0hist0[0],f0pc4[0],f0way[0],f0brend[0],f0ret[0]} = brdata0final[BRDATA_SIZE-1:0];
346 :
347 : assign {f1index[1],f1dbecc[1],f1icaf[1],f1hist1[1],f1hist0[1],f1pc4[1],f1way[1],f1brend[1],f1ret[1],
348 : f1index[0],f1dbecc[0],f1icaf[0],f1hist1[0],f1hist0[0],f1pc4[0],f1way[0],f1brend[0],f1ret[0]} = brdata1final[BRDATA_SIZE-1:0];
349 :
350 : end
351 : else begin
352 : assign brdata_in[BRDATA_SIZE-1:0] = {
353 : iccm_rd_ecc_double_err[1],ic_access_fault_f[1],ifu_bp_hist1_f[1],ifu_bp_hist0_f[1],ifu_bp_pc4_f[1],ifu_bp_way_f[1],ifu_bp_valid_f[1],ifu_bp_ret_f[1],
354 : iccm_rd_ecc_double_err[0],ic_access_fault_f[0],ifu_bp_hist1_f[0],ifu_bp_hist0_f[0],ifu_bp_pc4_f[0],ifu_bp_way_f[0],ifu_bp_valid_f[0],ifu_bp_ret_f[0]
355 : };
356 : assign {f0dbecc[1],f0icaf[1],f0hist1[1],f0hist0[1],f0pc4[1],f0way[1],f0brend[1],f0ret[1],
357 : f0dbecc[0],f0icaf[0],f0hist1[0],f0hist0[0],f0pc4[0],f0way[0],f0brend[0],f0ret[0]} = brdata0final[BRDATA_SIZE-1:0];
358 :
359 : assign {f1dbecc[1],f1icaf[1],f1hist1[1],f1hist0[1],f1pc4[1],f1way[1],f1brend[1],f1ret[1],
360 : f1dbecc[0],f1icaf[0],f1hist1[0],f1hist0[0],f1pc4[0],f1way[0],f1brend[0],f1ret[0]} = brdata1final[BRDATA_SIZE-1:0];
361 :
362 : end
363 :
364 :
365 :
366 :
367 : assign {brdata1eff[BRDATA_SIZE-1:0],brdata0eff[BRDATA_SIZE-1:0]} = (({BRDATA_SIZE*2{qren[0]}} & {brdata1[BRDATA_SIZE-1:0],brdata0[BRDATA_SIZE-1:0]}) |
368 : ({BRDATA_SIZE*2{qren[1]}} & {brdata2[BRDATA_SIZE-1:0],brdata1[BRDATA_SIZE-1:0]}) |
369 : ({BRDATA_SIZE*2{qren[2]}} & {brdata0[BRDATA_SIZE-1:0],brdata2[BRDATA_SIZE-1:0]}));
370 :
371 : assign brdata0final[BRDATA_SIZE-1:0] = (({BRDATA_SIZE{q0sel[0]}} & { brdata0eff[2*BRDATA_WIDTH-1:0]}) |
372 : ({BRDATA_SIZE{q0sel[1]}} & {{BRDATA_WIDTH{1'b0}},brdata0eff[BRDATA_SIZE-1:BRDATA_WIDTH]}));
373 :
374 : assign brdata1final[BRDATA_SIZE-1:0] = (({BRDATA_SIZE{q1sel[0]}} & { brdata1eff[2*BRDATA_WIDTH-1:0]}) |
375 : ({BRDATA_SIZE{q1sel[1]}} & {{BRDATA_WIDTH{1'b0}},brdata1eff[BRDATA_SIZE-1:BRDATA_WIDTH]}));
376 :
377 : end // if (pt.BTB_ENABLE==1)
378 : else begin
379 : assign {
380 : f1ictype[1:0]
381 : } = misc1eff[MHI:0];
382 :
383 : assign {
384 : f0ictype[1:0]
385 : } = misc0eff[MHI:0];
386 :
387 : assign brdata_in[BRDATA_SIZE-1:0] = {
388 : iccm_rd_ecc_double_err[1],ic_access_fault_f[1],
389 : iccm_rd_ecc_double_err[0],ic_access_fault_f[0]
390 : };
391 : assign {f0dbecc[1],f0icaf[1],
392 : f0dbecc[0],f0icaf[0]} = brdata0final[BRDATA_SIZE-1:0];
393 :
394 : assign {f1dbecc[1],f1icaf[1],
395 : f1dbecc[0],f1icaf[0]} = brdata1final[BRDATA_SIZE-1:0];
396 :
397 : assign {brdata1eff[BRDATA_SIZE-1:0],brdata0eff[BRDATA_SIZE-1:0]} = (({BRDATA_SIZE*2{qren[0]}} & {brdata1[BRDATA_SIZE-1:0],brdata0[BRDATA_SIZE-1:0]}) |
398 : ({BRDATA_SIZE*2{qren[1]}} & {brdata2[BRDATA_SIZE-1:0],brdata1[BRDATA_SIZE-1:0]}) |
399 : ({BRDATA_SIZE*2{qren[2]}} & {brdata0[BRDATA_SIZE-1:0],brdata2[BRDATA_SIZE-1:0]}));
400 :
401 : assign brdata0final[BRDATA_SIZE-1:0] = (({BRDATA_SIZE{q0sel[0]}} & { brdata0eff[2*BRDATA_WIDTH-1:0]}) |
402 : ({BRDATA_SIZE{q0sel[1]}} & {{BRDATA_WIDTH{1'b0}},brdata0eff[BRDATA_SIZE-1:BRDATA_WIDTH]}));
403 :
404 : assign brdata1final[BRDATA_SIZE-1:0] = (({BRDATA_SIZE{q1sel[0]}} & { brdata1eff[2*BRDATA_WIDTH-1:0]}) |
405 : ({BRDATA_SIZE{q1sel[1]}} & {{BRDATA_WIDTH{1'b0}},brdata1eff[BRDATA_SIZE-1:BRDATA_WIDTH]}));
406 :
407 : end // else: !if(pt.BTB_ENABLE==1)
408 :
409 :
410 : // possible states of { sf0_valid, sf1_valid, f2_valid }
411 : //
412 : // 000 if->f0
413 : // 100 if->f1
414 : // 101 illegal
415 : // 010 if->f1, f1->f0
416 : // 110 if->f2
417 : // 001 if->f1, f2->f0
418 : // 011 if->f2, f2->f1, f1->f0
419 : // 111 !if, no shift
420 :
421 : assign f2_valid = f2val[0];
422 : assign sf1_valid = sf1val[0];
423 : assign sf0_valid = sf0val[0];
424 :
425 : // interface to fetch
426 :
427 : assign consume_fb0 = ~sf0val[0] & f0val[0];
428 :
429 : assign consume_fb1 = ~sf1val[0] & f1val[0];
430 :
431 : assign ifu_fb_consume1 = consume_fb0 & ~consume_fb1 & ~exu_flush_final;
432 : assign ifu_fb_consume2 = consume_fb0 & consume_fb1 & ~exu_flush_final;
433 :
434 : assign ifvalid = ifu_fetch_val[0];
435 :
436 : assign shift_f1_f0 = ~sf0_valid & sf1_valid;
437 : assign shift_f2_f0 = ~sf0_valid & ~sf1_valid & f2_valid;
438 : assign shift_f2_f1 = ~sf0_valid & sf1_valid & f2_valid;
439 :
440 : assign fetch_to_f0 = ~sf0_valid & ~sf1_valid & ~f2_valid & ifvalid;
441 :
442 : assign fetch_to_f1 = (~sf0_valid & ~sf1_valid & f2_valid & ifvalid) |
443 : (~sf0_valid & sf1_valid & ~f2_valid & ifvalid) |
444 : ( sf0_valid & ~sf1_valid & ~f2_valid & ifvalid);
445 :
446 : assign fetch_to_f2 = (~sf0_valid & sf1_valid & f2_valid & ifvalid) |
447 : ( sf0_valid & sf1_valid & ~f2_valid & ifvalid);
448 :
449 :
450 : assign f2val_in[1:0] = ({2{ fetch_to_f2 & ~exu_flush_final}} & ifu_fetch_val[1:0]) |
451 : ({2{~fetch_to_f2 & ~shift_f2_f1 & ~shift_f2_f0 & ~exu_flush_final}} & f2val[1:0] );
452 :
453 :
454 : assign sf1val[1:0] = ({2{ f1_shift_2B}} & {1'b0,f1val[1]}) |
455 : ({2{~f1_shift_2B}} & f1val[1:0] );
456 :
457 : assign f1val_in[1:0] = ({2{ fetch_to_f1 & ~exu_flush_final}} & ifu_fetch_val[1:0]) |
458 : ({2{ shift_f2_f1 & ~exu_flush_final}} & f2val[1:0] ) |
459 : ({2{~fetch_to_f1 & ~shift_f2_f1 & ~shift_f1_f0 & ~exu_flush_final}} & sf1val[1:0] );
460 :
461 :
462 :
463 : assign sf0val[1:0] = ({2{ shift_2B }} & {1'b0,f0val[1]}) |
464 : ({2{~shift_2B & ~shift_4B}} & f0val[1:0]);
465 :
466 : assign f0val_in[1:0] = ({2{fetch_to_f0 & ~exu_flush_final}} & ifu_fetch_val[1:0]) |
467 : ({2{ shift_f2_f0 & ~exu_flush_final}} & f2val[1:0] ) |
468 : ({2{ shift_f1_f0 & ~exu_flush_final}} & sf1val[1:0] ) |
469 : ({2{~fetch_to_f0 & ~shift_f2_f0 & ~shift_f1_f0 & ~exu_flush_final}} & sf0val[1:0] );
470 :
471 : assign {q1eff[31:0],q0eff[31:0]} = (({64{qren[0]}} & {q1[31:0],q0[31:0]}) |
472 : ({64{qren[1]}} & {q2[31:0],q1[31:0]}) |
473 : ({64{qren[2]}} & {q0[31:0],q2[31:0]}));
474 :
475 : assign q0final[31:0] = ({32{q0sel[0]}} & { q0eff[31:0]}) |
476 : ({32{q0sel[1]}} & {16'b0,q0eff[31:16]});
477 :
478 : assign q1final[15:0] = ({16{q1sel[0]}} & q1eff[15:0] ) |
479 : ({16{q1sel[1]}} & q1eff[31:16]);
480 1322 : logic [31:1] q0pceff, q0pcfinal;
481 342 : logic [31:1] q1pceff;
482 :
483 : assign {q1pceff[31:1],q0pceff[31:1]} = (({62{qren[0]}} & {q1pc[31:1],q0pc[31:1]}) |
484 : ({62{qren[1]}} & {q2pc[31:1],q1pc[31:1]}) |
485 : ({62{qren[2]}} & {q0pc[31:1],q2pc[31:1]}));
486 :
487 :
488 : assign q0pcfinal[31:1] = ({31{q0sel[0]}} & ( q0pceff[31:1])) |
489 : ({31{q0sel[1]}} & ( q0pceff[31:1] + 31'd1));
490 :
491 : assign aligndata[31:0] = ({32{ f0val[1] }} & {q0final[31:0]}) |
492 : ({32{~f0val[1] & f0val[0]}} & {q1final[15:0],q0final[15:0]});
493 :
494 : assign alignval[1:0] = ({ 2{ f0val[1] }} & {2'b11}) |
495 : ({ 2{~f0val[1] & f0val[0]}} & {f1val[0],1'b1});
496 :
497 : assign alignicaf[1:0] = ({ 2{ f0val[1] }} & f0icaf[1:0] ) |
498 : ({ 2{~f0val[1] & f0val[0]}} & {f1icaf[0],f0icaf[0]});
499 :
500 : assign aligndbecc[1:0] = ({ 2{ f0val[1] }} & f0dbecc[1:0] ) |
501 : ({ 2{~f0val[1] & f0val[0]}} & {f1dbecc[0],f0dbecc[0]});
502 :
503 : if (pt.BTB_ENABLE==1) begin
504 :
505 : // for branch prediction
506 :
507 : assign alignbrend[1:0] = ({ 2{ f0val[1] }} & f0brend[1:0] ) |
508 : ({ 2{~f0val[1] & f0val[0]}} & {f1brend[0],f0brend[0]});
509 :
510 : assign alignpc4[1:0] = ({ 2{ f0val[1] }} & f0pc4[1:0] ) |
511 : ({ 2{~f0val[1] & f0val[0]}} & {f1pc4[0],f0pc4[0]});
512 :
513 : if(pt.BTB_FULLYA) begin
514 : assign alignindex[0] = f0index[0];
515 : assign alignindex[1] = f0val[1] ? f0index[1] : f1index[0];
516 : end
517 :
518 : assign alignret[1:0] = ({ 2{ f0val[1] }} & f0ret[1:0] ) |
519 : ({ 2{~f0val[1] & f0val[0]}} & {f1ret[0],f0ret[0]});
520 :
521 : assign alignway[1:0] = ({ 2{ f0val[1] }} & f0way[1:0] ) |
522 : ({ 2{~f0val[1] & f0val[0]}} & {f1way[0],f0way[0]});
523 :
524 : assign alignhist1[1:0] = ({ 2{ f0val[1] }} & f0hist1[1:0] ) |
525 : ({ 2{~f0val[1] & f0val[0]}} & {f1hist1[0],f0hist1[0]});
526 :
527 : assign alignhist0[1:0] = ({ 2{ f0val[1] }} & f0hist0[1:0] ) |
528 : ({ 2{~f0val[1] & f0val[0]}} & {f1hist0[0],f0hist0[0]});
529 :
530 : assign secondpc[31:1] = ({31{ f0val[1] }} & (q0pceff[31:1] + 31'd1)) |
531 : // you need the base pc for 2nd one only (4B max, 2B for the 1st and 2B for the 2nd)
532 : ({31{~f0val[1] & f0val[0]}} & q1pceff[31:1] );
533 :
534 :
535 : assign firstpc[31:1] = q0pcfinal[31:1];
536 : end // if (pt.BTB_ENABLE==1)
537 :
538 : assign alignfromf1[1] = ~f0val[1] & f0val[0];
539 :
540 :
541 : assign ifu_i0_pc[31:1] = q0pcfinal[31:1];
542 :
543 :
544 : assign ifu_i0_pc4 = first4B;
545 :
546 :
547 : assign ifu_i0_cinst[15:0] = aligndata[15:0];
548 :
549 : assign first4B = (aligndata[1:0] == 2'b11);
550 : assign first2B = ~first4B;
551 :
552 : assign ifu_i0_valid = (first4B & alignval[1]) |
553 : (first2B & alignval[0]);
554 :
555 : // inst access fault on any byte of inst results in access fault for the inst
556 : assign ifu_i0_icaf = (first4B & (|alignicaf[1:0])) |
557 : (first2B & alignicaf[0] );
558 :
559 : assign ifu_i0_icaf_type[1:0] = (first4B & ~f0val[1] & f0val[0] & ~alignicaf[0] & ~aligndbecc[0]) ? f1ictype[1:0] : f0ictype[1:0];
560 :
561 :
562 : assign icaf_eff[1:0] = alignicaf[1:0] | aligndbecc[1:0];
563 :
564 : assign ifu_i0_icaf_second = first4B & ~icaf_eff[0] & icaf_eff[1];
565 :
566 : assign ifu_i0_dbecc = (first4B & (|aligndbecc[1:0])) |
567 : (first2B & aligndbecc[0] );
568 :
569 :
570 : assign ifirst[31:0] = aligndata[31:0];
571 :
572 :
573 : assign ifu_i0_instr[31:0] = ({32{first4B & alignval[1]}} & ifirst[31:0]) |
574 : ({32{first2B & alignval[0]}} & uncompress0[31:0]);
575 :
576 : if(pt.BTB_ENABLE==1) begin : genblock2
577 :
578 : // if you detect br does not start on instruction boundary
579 :
580 : el2_btb_addr_hash #(.pt(pt)) firsthash (.pc(firstpc [pt.BTB_INDEX3_HI:pt.BTB_INDEX1_LO]),
581 : .hash(firstpc_hash [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO]));
582 : el2_btb_addr_hash #(.pt(pt)) secondhash(.pc(secondpc[pt.BTB_INDEX3_HI:pt.BTB_INDEX1_LO]),
583 : .hash(secondpc_hash[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO]));
584 :
585 : if(pt.BTB_FULLYA) begin
586 : assign firstbrtag_hash = firstpc;
587 : assign secondbrtag_hash = secondpc;
588 : end
589 : else begin
590 : if(pt.BTB_BTAG_FOLD) begin : btbfold
591 : el2_btb_tag_hash_fold #(.pt(pt)) first_brhash (.pc(firstpc [pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+1]),
592 : .hash(firstbrtag_hash [pt.BTB_BTAG_SIZE-1:0]));
593 : el2_btb_tag_hash_fold #(.pt(pt)) second_brhash(.pc(secondpc[pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+1]),
594 : .hash(secondbrtag_hash[pt.BTB_BTAG_SIZE-1:0]));
595 : end
596 : else begin : btbfold
597 : el2_btb_tag_hash #(.pt(pt)) first_brhash (.pc(firstpc [pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+1]),
598 : .hash(firstbrtag_hash [pt.BTB_BTAG_SIZE-1:0]));
599 : el2_btb_tag_hash #(.pt(pt)) second_brhash(.pc(secondpc[pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+1]),
600 : .hash(secondbrtag_hash[pt.BTB_BTAG_SIZE-1:0]));
601 : end
602 : end // else: !if(pt.BTB_FULLYA)
603 :
604 :
605 : // start_indexing - you want pc to be based on where the end of branch is prediction
606 : // normal indexing pc based that's incorrect now for pc4 cases it's pc4 + 2
607 :
608 339 : always_comb begin
609 :
610 339 : i0_brp = '0;
611 :
612 339 : i0_br_start_error = (first4B & alignval[1] & alignbrend[0]);
613 :
614 339 : i0_brp.valid = (first2B & alignbrend[0]) |
615 339 : (first4B & alignbrend[1]) |
616 339 : i0_br_start_error;
617 :
618 339 : i0_brp_pc4 = (first2B & alignpc4[0]) |
619 339 : (first4B & alignpc4[1]);
620 :
621 339 : i0_brp.ret = (first2B & alignret[0]) |
622 339 : (first4B & alignret[1]);
623 :
624 339 : i0_brp.way = (first2B | alignbrend[0]) ? alignway[0] : alignway[1];
625 :
626 339 : i0_brp.hist[1] = (first2B & alignhist1[0]) |
627 339 : (first4B & alignhist1[1]);
628 :
629 339 : i0_brp.hist[0] = (first2B & alignhist0[0]) |
630 339 : (first4B & alignhist0[1]);
631 :
632 339 : i0_ends_f1 = first4B & alignfromf1[1];
633 :
634 339 : i0_brp.toffset[11:0] = (i0_ends_f1) ? f1poffset[11:0] : f0poffset[11:0];
635 :
636 339 : i0_brp.prett[31:1] = (i0_ends_f1) ? f1prett[31:1] : f0prett[31:1];
637 :
638 339 : i0_brp.br_start_error = i0_br_start_error;
639 :
640 339 : i0_brp.bank = (first2B | alignbrend[0]) ? firstpc[1] : secondpc[1];
641 :
642 339 : i0_brp.br_error = (i0_brp.valid & i0_brp_pc4 & first2B) |
643 339 : (i0_brp.valid & ~i0_brp_pc4 & first4B);
644 :
645 339 : if(pt.BTB_FULLYA)
646 0 : ifu_i0_fa_index = (first2B | alignbrend[0]) ? alignindex[0] : alignindex[1];
647 : else
648 339 : ifu_i0_fa_index = '0;
649 :
650 : end
651 :
652 :
653 : assign ifu_i0_bp_index[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] = (first2B | alignbrend[0]) ? firstpc_hash[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] :
654 : secondpc_hash[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO];
655 :
656 : assign ifu_i0_bp_fghr[pt.BHT_GHR_SIZE-1:0] = (i0_ends_f1) ? f1fghr[pt.BHT_GHR_SIZE-1:0] :
657 : f0fghr[pt.BHT_GHR_SIZE-1:0];
658 :
659 : assign ifu_i0_bp_btag[pt.BTB_BTAG_SIZE-1:0] = (first2B | alignbrend[0]) ? firstbrtag_hash[pt.BTB_BTAG_SIZE-1:0] :
660 : secondbrtag_hash[pt.BTB_BTAG_SIZE-1:0];
661 : end
662 : else begin
663 : assign i0_brp = '0;
664 : assign ifu_i0_bp_index = '0;
665 : assign ifu_i0_bp_fghr = '0;
666 : assign ifu_i0_bp_btag = '0;
667 : end // else: !if(pt.BTB_ENABLE==1)
668 :
669 : // decompress
670 :
671 : // quiet inputs for 4B inst
672 : el2_ifu_compress_ctl compress0 (.din((first2B) ? aligndata[15:0] : '0), .dout(uncompress0[31:0]));
673 :
674 :
675 :
676 : assign i0_shift = dec_i0_decode_d & ~error_stall;
677 :
678 : assign ifu_pmu_instr_aligned = i0_shift;
679 :
680 :
681 : // compute how many bytes are being shifted from f0
682 :
683 : assign shift_2B = i0_shift & first2B;
684 :
685 : assign shift_4B = i0_shift & first4B;
686 :
687 : // exact equations for the queue logic
688 : assign f0_shift_2B = (shift_2B & f0val[0] ) |
689 : (shift_4B & f0val[0] & ~f0val[1]);
690 :
691 :
692 : // f0 valid states
693 : // 11
694 : // 10
695 : // 00
696 :
697 : assign f1_shift_2B = f0val[0] & ~f0val[1] & shift_4B;
698 :
699 :
700 :
701 : endmodule
|